forked from mirrors/gecko-dev
		
	Source-Repo: https://github.com/servo/servo Source-Revision: b1305bb7d051f83850c51bb0da0ccc86a5e07922 --HG-- rename : servo/src/components/canvas/canvas_render_task.rs => servo/components/canvas/canvas_render_task.rs rename : servo/src/components/canvas/canvas.rs => servo/components/canvas/lib.rs rename : servo/src/components/compositing/compositor.rs => servo/components/compositing/compositor.rs rename : servo/src/components/compositing/compositor_data.rs => servo/components/compositing/compositor_data.rs rename : servo/src/components/compositing/compositor_task.rs => servo/components/compositing/compositor_task.rs rename : servo/src/components/compositing/constellation.rs => servo/components/compositing/constellation.rs rename : servo/src/components/compositing/events.rs => servo/components/compositing/events.rs rename : servo/src/components/compositing/headless.rs => servo/components/compositing/headless.rs rename : servo/src/components/compositing/compositing.rs => servo/components/compositing/lib.rs rename : servo/src/components/compositing/pipeline.rs => servo/components/compositing/pipeline.rs rename : servo/src/components/compositing/platform/common/glfw_windowing.rs => servo/components/compositing/platform/common/glfw_windowing.rs rename : servo/src/components/compositing/platform/common/glut_windowing.rs => servo/components/compositing/platform/common/glut_windowing.rs rename : servo/src/components/compositing/platform/mod.rs => servo/components/compositing/platform/mod.rs rename : servo/src/components/compositing/windowing.rs => servo/components/compositing/windowing.rs rename : servo/src/components/gfx/buffer_map.rs => servo/components/gfx/buffer_map.rs rename : servo/src/components/gfx/color.rs => servo/components/gfx/color.rs rename : servo/src/components/gfx/display_list/mod.rs => servo/components/gfx/display_list/mod.rs rename : servo/src/components/gfx/display_list/optimizer.rs => servo/components/gfx/display_list/optimizer.rs rename : servo/src/components/gfx/font.rs => servo/components/gfx/font.rs rename : servo/src/components/gfx/font_cache_task.rs => servo/components/gfx/font_cache_task.rs rename : servo/src/components/gfx/font_context.rs => servo/components/gfx/font_context.rs rename : servo/src/components/gfx/font_template.rs => servo/components/gfx/font_template.rs rename : servo/src/components/gfx/gfx.rs => servo/components/gfx/lib.rs rename : servo/src/components/gfx/platform/freetype/font.rs => servo/components/gfx/platform/freetype/font.rs rename : servo/src/components/gfx/platform/freetype/font_context.rs => servo/components/gfx/platform/freetype/font_context.rs rename : servo/src/components/gfx/platform/freetype/font_list.rs => servo/components/gfx/platform/freetype/font_list.rs rename : servo/src/components/gfx/platform/freetype/font_template.rs => servo/components/gfx/platform/freetype/font_template.rs rename : servo/src/components/gfx/platform/macos/font.rs => servo/components/gfx/platform/macos/font.rs rename : servo/src/components/gfx/platform/macos/font_context.rs => servo/components/gfx/platform/macos/font_context.rs rename : servo/src/components/gfx/platform/macos/font_list.rs => servo/components/gfx/platform/macos/font_list.rs rename : servo/src/components/gfx/platform/macos/font_template.rs => servo/components/gfx/platform/macos/font_template.rs rename : servo/src/components/gfx/platform/mod.rs => servo/components/gfx/platform/mod.rs rename : servo/src/components/gfx/render_context.rs => servo/components/gfx/render_context.rs rename : servo/src/components/gfx/render_task.rs => servo/components/gfx/render_task.rs rename : servo/src/components/gfx/text/glyph.rs => servo/components/gfx/text/glyph.rs rename : servo/src/components/gfx/text/mod.rs => servo/components/gfx/text/mod.rs rename : servo/src/components/gfx/text/shaping/harfbuzz.rs => servo/components/gfx/text/shaping/harfbuzz.rs rename : servo/src/components/gfx/text/shaping/mod.rs => servo/components/gfx/text/shaping/mod.rs rename : servo/src/components/gfx/text/text_run.rs => servo/components/gfx/text/text_run.rs rename : servo/src/components/gfx/text/util.rs => servo/components/gfx/text/util.rs rename : servo/src/components/layout/block.rs => servo/components/layout/block.rs rename : servo/src/components/layout/construct.rs => servo/components/layout/construct.rs rename : servo/src/components/layout/context.rs => servo/components/layout/context.rs rename : servo/src/components/layout/css/matching.rs => servo/components/layout/css/matching.rs rename : servo/src/components/layout/css/node_style.rs => servo/components/layout/css/node_style.rs rename : servo/src/components/layout/css/node_util.rs => servo/components/layout/css/node_util.rs rename : servo/src/components/layout/extra.rs => servo/components/layout/extra.rs rename : servo/src/components/layout/floats.rs => servo/components/layout/floats.rs rename : servo/src/components/layout/flow.rs => servo/components/layout/flow.rs rename : servo/src/components/layout/flow_list.rs => servo/components/layout/flow_list.rs rename : servo/src/components/layout/flow_ref.rs => servo/components/layout/flow_ref.rs rename : servo/src/components/layout/fragment.rs => servo/components/layout/fragment.rs rename : servo/src/components/layout/incremental.rs => servo/components/layout/incremental.rs rename : servo/src/components/layout/inline.rs => servo/components/layout/inline.rs rename : servo/src/components/layout/layout_debug.rs => servo/components/layout/layout_debug.rs rename : servo/src/components/layout/layout_task.rs => servo/components/layout/layout_task.rs rename : servo/src/components/layout/layout.rs => servo/components/layout/lib.rs rename : servo/src/components/layout/model.rs => servo/components/layout/model.rs rename : servo/src/components/layout/parallel.rs => servo/components/layout/parallel.rs rename : servo/src/components/layout/table.rs => servo/components/layout/table.rs rename : servo/src/components/layout/table_caption.rs => servo/components/layout/table_caption.rs rename : servo/src/components/layout/table_cell.rs => servo/components/layout/table_cell.rs rename : servo/src/components/layout/table_colgroup.rs => servo/components/layout/table_colgroup.rs rename : servo/src/components/layout/table_row.rs => servo/components/layout/table_row.rs rename : servo/src/components/layout/table_rowgroup.rs => servo/components/layout/table_rowgroup.rs rename : servo/src/components/layout/table_wrapper.rs => servo/components/layout/table_wrapper.rs rename : servo/src/components/layout/text.rs => servo/components/layout/text.rs rename : servo/src/components/layout/util.rs => servo/components/layout/util.rs rename : servo/src/components/layout/wrapper.rs => servo/components/layout/wrapper.rs rename : servo/src/components/layout_traits/layout_traits.rs => servo/components/layout_traits/lib.rs rename : servo/src/components/macros/macros.rs => servo/components/macros/lib.rs rename : servo/src/components/msg/compositor_msg.rs => servo/components/msg/compositor_msg.rs rename : servo/src/components/msg/constellation_msg.rs => servo/components/msg/constellation_msg.rs rename : servo/src/components/msg/msg.rs => servo/components/msg/lib.rs rename : servo/src/components/msg/platform/android/surface.rs => servo/components/msg/platform/android/surface.rs rename : servo/src/components/msg/platform/linux/surface.rs => servo/components/msg/platform/linux/surface.rs rename : servo/src/components/msg/platform/macos/surface.rs => servo/components/msg/platform/macos/surface.rs rename : servo/src/components/msg/platform/surface.rs => servo/components/msg/platform/surface.rs rename : servo/src/components/net/data_loader.rs => servo/components/net/data_loader.rs rename : servo/src/components/net/fetch/cors_cache.rs => servo/components/net/fetch/cors_cache.rs rename : servo/src/components/net/fetch/request.rs => servo/components/net/fetch/request.rs rename : servo/src/components/net/fetch/response.rs => servo/components/net/fetch/response.rs rename : servo/src/components/net/file_loader.rs => servo/components/net/file_loader.rs rename : servo/src/components/net/http_loader.rs => servo/components/net/http_loader.rs rename : servo/src/components/net/image/base.rs => servo/components/net/image/base.rs rename : servo/src/components/net/image/holder.rs => servo/components/net/image/holder.rs rename : servo/src/components/net/image/test.jpeg => servo/components/net/image/test.jpeg rename : servo/src/components/net/image_cache_task.rs => servo/components/net/image_cache_task.rs rename : servo/src/components/net/net.rs => servo/components/net/lib.rs rename : servo/src/components/net/local_image_cache.rs => servo/components/net/local_image_cache.rs rename : servo/src/components/net/resource_task.rs => servo/components/net/resource_task.rs rename : servo/src/components/script/cors.rs => servo/components/script/cors.rs rename : servo/src/components/script/dom/attr.rs => servo/components/script/dom/attr.rs rename : servo/src/components/script/dom/bindings/DESIGN.md => servo/components/script/dom/bindings/DESIGN.md rename : servo/src/components/script/dom/bindings/callback.rs => servo/components/script/dom/bindings/callback.rs rename : servo/src/components/script/dom/bindings/codegen/BindingGen.py => servo/components/script/dom/bindings/codegen/BindingGen.py rename : servo/src/components/script/dom/bindings/codegen/BindingUtils.cpp => servo/components/script/dom/bindings/codegen/BindingUtils.cpp rename : servo/src/components/script/dom/bindings/codegen/BindingUtils.h => servo/components/script/dom/bindings/codegen/BindingUtils.h rename : servo/src/components/script/dom/bindings/codegen/Bindings.conf => servo/components/script/dom/bindings/codegen/Bindings.conf rename : servo/src/components/script/dom/bindings/codegen/Codegen.py => servo/components/script/dom/bindings/codegen/Codegen.py rename : servo/src/components/script/dom/bindings/codegen/CodegenRust.py => servo/components/script/dom/bindings/codegen/CodegenRust.py rename : servo/src/components/script/dom/bindings/codegen/Configuration.py => servo/components/script/dom/bindings/codegen/Configuration.py rename : servo/src/components/script/dom/bindings/codegen/DOMJSClass.h => servo/components/script/dom/bindings/codegen/DOMJSClass.h rename : servo/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp => servo/components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp rename : servo/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.h => servo/components/script/dom/bindings/codegen/DOMJSProxyHandler.h rename : servo/src/components/script/dom/bindings/codegen/ErrorResult.h => servo/components/script/dom/bindings/codegen/ErrorResult.h rename : servo/src/components/script/dom/bindings/codegen/Errors.msg => servo/components/script/dom/bindings/codegen/Errors.msg rename : servo/src/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py => servo/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py rename : servo/src/components/script/dom/bindings/codegen/GlobalGen.py => servo/components/script/dom/bindings/codegen/GlobalGen.py rename : servo/src/components/script/dom/bindings/codegen/Makefile.in => servo/components/script/dom/bindings/codegen/Makefile.in rename : servo/src/components/script/dom/bindings/codegen/Nullable.h => servo/components/script/dom/bindings/codegen/Nullable.h rename : servo/src/components/script/dom/bindings/codegen/PrimitiveConversions.h => servo/components/script/dom/bindings/codegen/PrimitiveConversions.h rename : servo/src/components/script/dom/bindings/codegen/RegisterBindings.h => servo/components/script/dom/bindings/codegen/RegisterBindings.h rename : servo/src/components/script/dom/bindings/codegen/TypedArray.h => servo/components/script/dom/bindings/codegen/TypedArray.h rename : servo/src/components/script/dom/bindings/codegen/crashtests/769464.html => servo/components/script/dom/bindings/codegen/crashtests/769464.html rename : servo/src/components/script/dom/bindings/codegen/crashtests/crashtests.list => servo/components/script/dom/bindings/codegen/crashtests/crashtests.list rename : servo/src/components/script/dom/bindings/codegen/parser/README => servo/components/script/dom/bindings/codegen/parser/README rename : servo/src/components/script/dom/bindings/codegen/parser/UPSTREAM => servo/components/script/dom/bindings/codegen/parser/UPSTREAM rename : servo/src/components/script/dom/bindings/codegen/parser/WebIDL.py => servo/components/script/dom/bindings/codegen/parser/WebIDL.py rename : servo/src/components/script/dom/bindings/codegen/parser/external.patch => servo/components/script/dom/bindings/codegen/parser/external.patch rename : servo/src/components/script/dom/bindings/codegen/parser/module.patch => servo/components/script/dom/bindings/codegen/parser/module.patch rename : servo/src/components/script/dom/bindings/codegen/parser/runtests.py => servo/components/script/dom/bindings/codegen/parser/runtests.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_any_null.py => servo/components/script/dom/bindings/codegen/parser/tests/test_any_null.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py => servo/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py => servo/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py => servo/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py => servo/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_attr.py => servo/components/script/dom/bindings/codegen/parser/tests/test_attr.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py => servo/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py => servo/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_builtins.py => servo/components/script/dom/bindings/codegen/parser/tests/test_builtins.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_callback.py => servo/components/script/dom/bindings/codegen/parser/tests/test_callback.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py => servo/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_const.py => servo/components/script/dom/bindings/codegen/parser/tests/test_const.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_constructor.py => servo/components/script/dom/bindings/codegen/parser/tests/test_constructor.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py => servo/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py => servo/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py => servo/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py => servo/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_double_null.py => servo/components/script/dom/bindings/codegen/parser/tests/test_double_null.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py => servo/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py => servo/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_enum.py => servo/components/script/dom/bindings/codegen/parser/tests/test_enum.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py => servo/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py => servo/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py => servo/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py => servo/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py => servo/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_implements.py => servo/components/script/dom/bindings/codegen/parser/tests/test_implements.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py => servo/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py => servo/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_interface.py => servo/components/script/dom/bindings/codegen/parser/tests/test_interface.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py => servo/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py => servo/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_method.py => servo/components/script/dom/bindings/codegen/parser/tests/test_method.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py => servo/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py => servo/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py => servo/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_overload.py => servo/components/script/dom/bindings/codegen/parser/tests/test_overload.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_sanity.py => servo/components/script/dom/bindings/codegen/parser/tests/test_sanity.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py => servo/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py => servo/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py => servo/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py => servo/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_typedef.py => servo/components/script/dom/bindings/codegen/parser/tests/test_typedef.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_union.py => servo/components/script/dom/bindings/codegen/parser/tests/test_union.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_union_any.py => servo/components/script/dom/bindings/codegen/parser/tests/test_union_any.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py => servo/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py => servo/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py rename : servo/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py => servo/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py rename : servo/src/components/script/dom/bindings/codegen/parser/update.sh => servo/components/script/dom/bindings/codegen/parser/update.sh rename : servo/src/components/script/dom/bindings/codegen/ply/COPYING => servo/components/script/dom/bindings/codegen/ply/COPYING rename : servo/src/components/script/dom/bindings/codegen/ply/README => servo/components/script/dom/bindings/codegen/ply/README rename : servo/src/components/script/dom/bindings/codegen/ply/ply/__init__.py => servo/components/script/dom/bindings/codegen/ply/ply/__init__.py rename : servo/src/components/script/dom/bindings/codegen/ply/ply/lex.py => servo/components/script/dom/bindings/codegen/ply/ply/lex.py rename : servo/src/components/script/dom/bindings/codegen/ply/ply/yacc.py => servo/components/script/dom/bindings/codegen/ply/ply/yacc.py rename : servo/src/components/script/dom/bindings/codegen/pythonpath.py => servo/components/script/dom/bindings/codegen/pythonpath.py rename : servo/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.cpp => servo/components/script/dom/bindings/codegen/stubgenerator/Skeleton.cpp rename : servo/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.h => servo/components/script/dom/bindings/codegen/stubgenerator/Skeleton.h rename : servo/src/components/script/dom/bindings/codegen/stubgenerator/generate.sh => servo/components/script/dom/bindings/codegen/stubgenerator/generate.sh rename : servo/src/components/script/dom/bindings/codegen/test/Makefile.in => servo/components/script/dom/bindings/codegen/test/Makefile.in rename : servo/src/components/script/dom/bindings/codegen/test/TestBindingHeader.h => servo/components/script/dom/bindings/codegen/test/TestBindingHeader.h rename : servo/src/components/script/dom/bindings/codegen/test/TestCodeGen.webidl => servo/components/script/dom/bindings/codegen/test/TestCodeGen.webidl rename : servo/src/components/script/dom/bindings/codegen/test/TestDictionary.webidl => servo/components/script/dom/bindings/codegen/test/TestDictionary.webidl rename : servo/src/components/script/dom/bindings/codegen/test/TestTypedef.webidl => servo/components/script/dom/bindings/codegen/test/TestTypedef.webidl rename : servo/src/components/script/dom/bindings/codegen/test/file_bug775543.html => servo/components/script/dom/bindings/codegen/test/file_bug775543.html rename : servo/src/components/script/dom/bindings/codegen/test/forOf_iframe.html => servo/components/script/dom/bindings/codegen/test/forOf_iframe.html rename : servo/src/components/script/dom/bindings/codegen/test/test_InstanceOf.html => servo/components/script/dom/bindings/codegen/test/test_InstanceOf.html rename : servo/src/components/script/dom/bindings/codegen/test/test_bug773326.html => servo/components/script/dom/bindings/codegen/test/test_bug773326.html rename : servo/src/components/script/dom/bindings/codegen/test/test_bug775543.html => servo/components/script/dom/bindings/codegen/test/test_bug775543.html rename : servo/src/components/script/dom/bindings/codegen/test/test_bug788369.html => servo/components/script/dom/bindings/codegen/test/test_bug788369.html rename : servo/src/components/script/dom/bindings/codegen/test/test_enums.html => servo/components/script/dom/bindings/codegen/test/test_enums.html rename : servo/src/components/script/dom/bindings/codegen/test/test_forOf.html => servo/components/script/dom/bindings/codegen/test/test_forOf.html rename : servo/src/components/script/dom/bindings/codegen/test/test_integers.html => servo/components/script/dom/bindings/codegen/test/test_integers.html rename : servo/src/components/script/dom/bindings/codegen/test/test_interfaceToString.html => servo/components/script/dom/bindings/codegen/test/test_interfaceToString.html rename : servo/src/components/script/dom/bindings/codegen/test/test_lookupGetter.html => servo/components/script/dom/bindings/codegen/test/test_lookupGetter.html rename : servo/src/components/script/dom/bindings/codegen/test/test_sequence_wrapping.html => servo/components/script/dom/bindings/codegen/test/test_sequence_wrapping.html rename : servo/src/components/script/dom/bindings/codegen/test/test_traceProtos.html => servo/components/script/dom/bindings/codegen/test/test_traceProtos.html rename : servo/src/components/script/dom/bindings/conversions.rs => servo/components/script/dom/bindings/conversions.rs rename : servo/src/components/script/dom/bindings/error.rs => servo/components/script/dom/bindings/error.rs rename : servo/src/components/script/dom/bindings/global.rs => servo/components/script/dom/bindings/global.rs rename : servo/src/components/script/dom/bindings/js.rs => servo/components/script/dom/bindings/js.rs rename : servo/src/components/script/dom/bindings/proxyhandler.rs => servo/components/script/dom/bindings/proxyhandler.rs rename : servo/src/components/script/dom/bindings/str.rs => servo/components/script/dom/bindings/str.rs rename : servo/src/components/script/dom/bindings/trace.rs => servo/components/script/dom/bindings/trace.rs rename : servo/src/components/script/dom/bindings/utils.rs => servo/components/script/dom/bindings/utils.rs rename : servo/src/components/script/dom/blob.rs => servo/components/script/dom/blob.rs rename : servo/src/components/script/dom/browsercontext.rs => servo/components/script/dom/browsercontext.rs rename : servo/src/components/script/dom/canvasrenderingcontext2d.rs => servo/components/script/dom/canvasrenderingcontext2d.rs rename : servo/src/components/script/dom/characterdata.rs => servo/components/script/dom/characterdata.rs rename : servo/src/components/script/dom/comment.rs => servo/components/script/dom/comment.rs rename : servo/src/components/script/dom/console.rs => servo/components/script/dom/console.rs rename : servo/src/components/script/dom/customevent.rs => servo/components/script/dom/customevent.rs rename : servo/src/components/script/dom/dedicatedworkerglobalscope.rs => servo/components/script/dom/dedicatedworkerglobalscope.rs rename : servo/src/components/script/dom/document.rs => servo/components/script/dom/document.rs rename : servo/src/components/script/dom/documentfragment.rs => servo/components/script/dom/documentfragment.rs rename : servo/src/components/script/dom/documenttype.rs => servo/components/script/dom/documenttype.rs rename : servo/src/components/script/dom/domexception.rs => servo/components/script/dom/domexception.rs rename : servo/src/components/script/dom/domimplementation.rs => servo/components/script/dom/domimplementation.rs rename : servo/src/components/script/dom/domparser.rs => servo/components/script/dom/domparser.rs rename : servo/src/components/script/dom/domrect.rs => servo/components/script/dom/domrect.rs rename : servo/src/components/script/dom/domrectlist.rs => servo/components/script/dom/domrectlist.rs rename : servo/src/components/script/dom/domtokenlist.rs => servo/components/script/dom/domtokenlist.rs rename : servo/src/components/script/dom/element.rs => servo/components/script/dom/element.rs rename : servo/src/components/script/dom/event.rs => servo/components/script/dom/event.rs rename : servo/src/components/script/dom/eventdispatcher.rs => servo/components/script/dom/eventdispatcher.rs rename : servo/src/components/script/dom/eventtarget.rs => servo/components/script/dom/eventtarget.rs rename : servo/src/components/script/dom/file.rs => servo/components/script/dom/file.rs rename : servo/src/components/script/dom/formdata.rs => servo/components/script/dom/formdata.rs rename : servo/src/components/script/dom/htmlanchorelement.rs => servo/components/script/dom/htmlanchorelement.rs rename : servo/src/components/script/dom/htmlappletelement.rs => servo/components/script/dom/htmlappletelement.rs rename : servo/src/components/script/dom/htmlareaelement.rs => servo/components/script/dom/htmlareaelement.rs rename : servo/src/components/script/dom/htmlaudioelement.rs => servo/components/script/dom/htmlaudioelement.rs rename : servo/src/components/script/dom/htmlbaseelement.rs => servo/components/script/dom/htmlbaseelement.rs rename : servo/src/components/script/dom/htmlbodyelement.rs => servo/components/script/dom/htmlbodyelement.rs rename : servo/src/components/script/dom/htmlbrelement.rs => servo/components/script/dom/htmlbrelement.rs rename : servo/src/components/script/dom/htmlbuttonelement.rs => servo/components/script/dom/htmlbuttonelement.rs rename : servo/src/components/script/dom/htmlcanvaselement.rs => servo/components/script/dom/htmlcanvaselement.rs rename : servo/src/components/script/dom/htmlcollection.rs => servo/components/script/dom/htmlcollection.rs rename : servo/src/components/script/dom/htmldataelement.rs => servo/components/script/dom/htmldataelement.rs rename : servo/src/components/script/dom/htmldatalistelement.rs => servo/components/script/dom/htmldatalistelement.rs rename : servo/src/components/script/dom/htmldirectoryelement.rs => servo/components/script/dom/htmldirectoryelement.rs rename : servo/src/components/script/dom/htmldivelement.rs => servo/components/script/dom/htmldivelement.rs rename : servo/src/components/script/dom/htmldlistelement.rs => servo/components/script/dom/htmldlistelement.rs rename : servo/src/components/script/dom/htmlelement.rs => servo/components/script/dom/htmlelement.rs rename : servo/src/components/script/dom/htmlembedelement.rs => servo/components/script/dom/htmlembedelement.rs rename : servo/src/components/script/dom/htmlfieldsetelement.rs => servo/components/script/dom/htmlfieldsetelement.rs rename : servo/src/components/script/dom/htmlfontelement.rs => servo/components/script/dom/htmlfontelement.rs rename : servo/src/components/script/dom/htmlformelement.rs => servo/components/script/dom/htmlformelement.rs rename : servo/src/components/script/dom/htmlframeelement.rs => servo/components/script/dom/htmlframeelement.rs rename : servo/src/components/script/dom/htmlframesetelement.rs => servo/components/script/dom/htmlframesetelement.rs rename : servo/src/components/script/dom/htmlheadelement.rs => servo/components/script/dom/htmlheadelement.rs rename : servo/src/components/script/dom/htmlheadingelement.rs => servo/components/script/dom/htmlheadingelement.rs rename : servo/src/components/script/dom/htmlhrelement.rs => servo/components/script/dom/htmlhrelement.rs rename : servo/src/components/script/dom/htmlhtmlelement.rs => servo/components/script/dom/htmlhtmlelement.rs rename : servo/src/components/script/dom/htmliframeelement.rs => servo/components/script/dom/htmliframeelement.rs rename : servo/src/components/script/dom/htmlimageelement.rs => servo/components/script/dom/htmlimageelement.rs rename : servo/src/components/script/dom/htmlinputelement.rs => servo/components/script/dom/htmlinputelement.rs rename : servo/src/components/script/dom/htmllabelelement.rs => servo/components/script/dom/htmllabelelement.rs rename : servo/src/components/script/dom/htmllegendelement.rs => servo/components/script/dom/htmllegendelement.rs rename : servo/src/components/script/dom/htmllielement.rs => servo/components/script/dom/htmllielement.rs rename : servo/src/components/script/dom/htmllinkelement.rs => servo/components/script/dom/htmllinkelement.rs rename : servo/src/components/script/dom/htmlmapelement.rs => servo/components/script/dom/htmlmapelement.rs rename : servo/src/components/script/dom/htmlmediaelement.rs => servo/components/script/dom/htmlmediaelement.rs rename : servo/src/components/script/dom/htmlmetaelement.rs => servo/components/script/dom/htmlmetaelement.rs rename : servo/src/components/script/dom/htmlmeterelement.rs => servo/components/script/dom/htmlmeterelement.rs rename : servo/src/components/script/dom/htmlmodelement.rs => servo/components/script/dom/htmlmodelement.rs rename : servo/src/components/script/dom/htmlobjectelement.rs => servo/components/script/dom/htmlobjectelement.rs rename : servo/src/components/script/dom/htmlolistelement.rs => servo/components/script/dom/htmlolistelement.rs rename : servo/src/components/script/dom/htmloptgroupelement.rs => servo/components/script/dom/htmloptgroupelement.rs rename : servo/src/components/script/dom/htmloptionelement.rs => servo/components/script/dom/htmloptionelement.rs rename : servo/src/components/script/dom/htmloutputelement.rs => servo/components/script/dom/htmloutputelement.rs rename : servo/src/components/script/dom/htmlparagraphelement.rs => servo/components/script/dom/htmlparagraphelement.rs rename : servo/src/components/script/dom/htmlparamelement.rs => servo/components/script/dom/htmlparamelement.rs rename : servo/src/components/script/dom/htmlpreelement.rs => servo/components/script/dom/htmlpreelement.rs rename : servo/src/components/script/dom/htmlprogresselement.rs => servo/components/script/dom/htmlprogresselement.rs rename : servo/src/components/script/dom/htmlquoteelement.rs => servo/components/script/dom/htmlquoteelement.rs rename : servo/src/components/script/dom/htmlscriptelement.rs => servo/components/script/dom/htmlscriptelement.rs rename : servo/src/components/script/dom/htmlselectelement.rs => servo/components/script/dom/htmlselectelement.rs rename : servo/src/components/script/dom/htmlserializer.rs => servo/components/script/dom/htmlserializer.rs rename : servo/src/components/script/dom/htmlsourceelement.rs => servo/components/script/dom/htmlsourceelement.rs rename : servo/src/components/script/dom/htmlspanelement.rs => servo/components/script/dom/htmlspanelement.rs rename : servo/src/components/script/dom/htmlstyleelement.rs => servo/components/script/dom/htmlstyleelement.rs rename : servo/src/components/script/dom/htmltablecaptionelement.rs => servo/components/script/dom/htmltablecaptionelement.rs rename : servo/src/components/script/dom/htmltablecellelement.rs => servo/components/script/dom/htmltablecellelement.rs rename : servo/src/components/script/dom/htmltablecolelement.rs => servo/components/script/dom/htmltablecolelement.rs rename : servo/src/components/script/dom/htmltabledatacellelement.rs => servo/components/script/dom/htmltabledatacellelement.rs rename : servo/src/components/script/dom/htmltableelement.rs => servo/components/script/dom/htmltableelement.rs rename : servo/src/components/script/dom/htmltableheadercellelement.rs => servo/components/script/dom/htmltableheadercellelement.rs rename : servo/src/components/script/dom/htmltablerowelement.rs => servo/components/script/dom/htmltablerowelement.rs rename : servo/src/components/script/dom/htmltablesectionelement.rs => servo/components/script/dom/htmltablesectionelement.rs rename : servo/src/components/script/dom/htmltemplateelement.rs => servo/components/script/dom/htmltemplateelement.rs rename : servo/src/components/script/dom/htmltextareaelement.rs => servo/components/script/dom/htmltextareaelement.rs rename : servo/src/components/script/dom/htmltimeelement.rs => servo/components/script/dom/htmltimeelement.rs rename : servo/src/components/script/dom/htmltitleelement.rs => servo/components/script/dom/htmltitleelement.rs rename : servo/src/components/script/dom/htmltrackelement.rs => servo/components/script/dom/htmltrackelement.rs rename : servo/src/components/script/dom/htmlulistelement.rs => servo/components/script/dom/htmlulistelement.rs rename : servo/src/components/script/dom/htmlunknownelement.rs => servo/components/script/dom/htmlunknownelement.rs rename : servo/src/components/script/dom/htmlvideoelement.rs => servo/components/script/dom/htmlvideoelement.rs rename : servo/src/components/script/dom/location.rs => servo/components/script/dom/location.rs rename : servo/src/components/script/dom/macros.rs => servo/components/script/dom/macros.rs rename : servo/src/components/script/dom/messageevent.rs => servo/components/script/dom/messageevent.rs rename : servo/src/components/script/dom/mouseevent.rs => servo/components/script/dom/mouseevent.rs rename : servo/src/components/script/dom/namednodemap.rs => servo/components/script/dom/namednodemap.rs rename : servo/src/components/script/dom/navigator.rs => servo/components/script/dom/navigator.rs rename : servo/src/components/script/dom/node.rs => servo/components/script/dom/node.rs rename : servo/src/components/script/dom/nodeiterator.rs => servo/components/script/dom/nodeiterator.rs rename : servo/src/components/script/dom/nodelist.rs => servo/components/script/dom/nodelist.rs rename : servo/src/components/script/dom/performance.rs => servo/components/script/dom/performance.rs rename : servo/src/components/script/dom/performancetiming.rs => servo/components/script/dom/performancetiming.rs rename : servo/src/components/script/dom/processinginstruction.rs => servo/components/script/dom/processinginstruction.rs rename : servo/src/components/script/dom/progressevent.rs => servo/components/script/dom/progressevent.rs rename : servo/src/components/script/dom/range.rs => servo/components/script/dom/range.rs rename : servo/src/components/script/dom/screen.rs => servo/components/script/dom/screen.rs rename : servo/src/components/script/dom/testbinding.rs => servo/components/script/dom/testbinding.rs rename : servo/src/components/script/dom/text.rs => servo/components/script/dom/text.rs rename : servo/src/components/script/dom/treewalker.rs => servo/components/script/dom/treewalker.rs rename : servo/src/components/script/dom/uievent.rs => servo/components/script/dom/uievent.rs rename : servo/src/components/script/dom/urlsearchparams.rs => servo/components/script/dom/urlsearchparams.rs rename : servo/src/components/script/dom/validitystate.rs => servo/components/script/dom/validitystate.rs rename : servo/src/components/script/dom/virtualmethods.rs => servo/components/script/dom/virtualmethods.rs rename : servo/src/components/script/dom/webidls/Attr.webidl => servo/components/script/dom/webidls/Attr.webidl rename : servo/src/components/script/dom/webidls/Blob.webidl => servo/components/script/dom/webidls/Blob.webidl rename : servo/src/components/script/dom/webidls/CanvasRenderingContext2D.webidl => servo/components/script/dom/webidls/CanvasRenderingContext2D.webidl rename : servo/src/components/script/dom/webidls/CharacterData.webidl => servo/components/script/dom/webidls/CharacterData.webidl rename : servo/src/components/script/dom/webidls/ChildNode.webidl => servo/components/script/dom/webidls/ChildNode.webidl rename : servo/src/components/script/dom/webidls/Comment.webidl => servo/components/script/dom/webidls/Comment.webidl rename : servo/src/components/script/dom/webidls/Console.webidl => servo/components/script/dom/webidls/Console.webidl rename : servo/src/components/script/dom/webidls/CustomEvent.webidl => servo/components/script/dom/webidls/CustomEvent.webidl rename : servo/src/components/script/dom/webidls/DOMException.webidl => servo/components/script/dom/webidls/DOMException.webidl rename : servo/src/components/script/dom/webidls/DOMImplementation.webidl => servo/components/script/dom/webidls/DOMImplementation.webidl rename : servo/src/components/script/dom/webidls/DOMParser.webidl => servo/components/script/dom/webidls/DOMParser.webidl rename : servo/src/components/script/dom/webidls/DOMRect.webidl => servo/components/script/dom/webidls/DOMRect.webidl rename : servo/src/components/script/dom/webidls/DOMRectList.webidl => servo/components/script/dom/webidls/DOMRectList.webidl rename : servo/src/components/script/dom/webidls/DOMTokenList.webidl => servo/components/script/dom/webidls/DOMTokenList.webidl rename : servo/src/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl => servo/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl rename : servo/src/components/script/dom/webidls/Document.webidl => servo/components/script/dom/webidls/Document.webidl rename : servo/src/components/script/dom/webidls/DocumentFragment.webidl => servo/components/script/dom/webidls/DocumentFragment.webidl rename : servo/src/components/script/dom/webidls/DocumentType.webidl => servo/components/script/dom/webidls/DocumentType.webidl rename : servo/src/components/script/dom/webidls/Element.webidl => servo/components/script/dom/webidls/Element.webidl rename : servo/src/components/script/dom/webidls/Event.webidl => servo/components/script/dom/webidls/Event.webidl rename : servo/src/components/script/dom/webidls/EventHandler.webidl => servo/components/script/dom/webidls/EventHandler.webidl rename : servo/src/components/script/dom/webidls/EventListener.webidl => servo/components/script/dom/webidls/EventListener.webidl rename : servo/src/components/script/dom/webidls/EventTarget.webidl => servo/components/script/dom/webidls/EventTarget.webidl rename : servo/src/components/script/dom/webidls/File.webidl => servo/components/script/dom/webidls/File.webidl rename : servo/src/components/script/dom/webidls/FormData.webidl => servo/components/script/dom/webidls/FormData.webidl rename : servo/src/components/script/dom/webidls/HTMLAnchorElement.webidl => servo/components/script/dom/webidls/HTMLAnchorElement.webidl rename : servo/src/components/script/dom/webidls/HTMLAppletElement.webidl => servo/components/script/dom/webidls/HTMLAppletElement.webidl rename : servo/src/components/script/dom/webidls/HTMLAreaElement.webidl => servo/components/script/dom/webidls/HTMLAreaElement.webidl rename : servo/src/components/script/dom/webidls/HTMLAudioElement.webidl => servo/components/script/dom/webidls/HTMLAudioElement.webidl rename : servo/src/components/script/dom/webidls/HTMLBRElement.webidl => servo/components/script/dom/webidls/HTMLBRElement.webidl rename : servo/src/components/script/dom/webidls/HTMLBaseElement.webidl => servo/components/script/dom/webidls/HTMLBaseElement.webidl rename : servo/src/components/script/dom/webidls/HTMLBodyElement.webidl => servo/components/script/dom/webidls/HTMLBodyElement.webidl rename : servo/src/components/script/dom/webidls/HTMLButtonElement.webidl => servo/components/script/dom/webidls/HTMLButtonElement.webidl rename : servo/src/components/script/dom/webidls/HTMLCanvasElement.webidl => servo/components/script/dom/webidls/HTMLCanvasElement.webidl rename : servo/src/components/script/dom/webidls/HTMLCollection.webidl => servo/components/script/dom/webidls/HTMLCollection.webidl rename : servo/src/components/script/dom/webidls/HTMLDListElement.webidl => servo/components/script/dom/webidls/HTMLDListElement.webidl rename : servo/src/components/script/dom/webidls/HTMLDataElement.webidl => servo/components/script/dom/webidls/HTMLDataElement.webidl rename : servo/src/components/script/dom/webidls/HTMLDataListElement.webidl => servo/components/script/dom/webidls/HTMLDataListElement.webidl rename : servo/src/components/script/dom/webidls/HTMLDirectoryElement.webidl => servo/components/script/dom/webidls/HTMLDirectoryElement.webidl rename : servo/src/components/script/dom/webidls/HTMLDivElement.webidl => servo/components/script/dom/webidls/HTMLDivElement.webidl rename : servo/src/components/script/dom/webidls/HTMLElement.webidl => servo/components/script/dom/webidls/HTMLElement.webidl rename : servo/src/components/script/dom/webidls/HTMLEmbedElement.webidl => servo/components/script/dom/webidls/HTMLEmbedElement.webidl rename : servo/src/components/script/dom/webidls/HTMLFieldSetElement.webidl => servo/components/script/dom/webidls/HTMLFieldSetElement.webidl rename : servo/src/components/script/dom/webidls/HTMLFontElement.webidl => servo/components/script/dom/webidls/HTMLFontElement.webidl rename : servo/src/components/script/dom/webidls/HTMLFormElement.webidl => servo/components/script/dom/webidls/HTMLFormElement.webidl rename : servo/src/components/script/dom/webidls/HTMLFrameElement.webidl => servo/components/script/dom/webidls/HTMLFrameElement.webidl rename : servo/src/components/script/dom/webidls/HTMLFrameSetElement.webidl => servo/components/script/dom/webidls/HTMLFrameSetElement.webidl rename : servo/src/components/script/dom/webidls/HTMLHRElement.webidl => servo/components/script/dom/webidls/HTMLHRElement.webidl rename : servo/src/components/script/dom/webidls/HTMLHeadElement.webidl => servo/components/script/dom/webidls/HTMLHeadElement.webidl rename : servo/src/components/script/dom/webidls/HTMLHeadingElement.webidl => servo/components/script/dom/webidls/HTMLHeadingElement.webidl rename : servo/src/components/script/dom/webidls/HTMLHtmlElement.webidl => servo/components/script/dom/webidls/HTMLHtmlElement.webidl rename : servo/src/components/script/dom/webidls/HTMLIFrameElement.webidl => servo/components/script/dom/webidls/HTMLIFrameElement.webidl rename : servo/src/components/script/dom/webidls/HTMLImageElement.webidl => servo/components/script/dom/webidls/HTMLImageElement.webidl rename : servo/src/components/script/dom/webidls/HTMLInputElement.webidl => servo/components/script/dom/webidls/HTMLInputElement.webidl rename : servo/src/components/script/dom/webidls/HTMLLIElement.webidl => servo/components/script/dom/webidls/HTMLLIElement.webidl rename : servo/src/components/script/dom/webidls/HTMLLabelElement.webidl => servo/components/script/dom/webidls/HTMLLabelElement.webidl rename : servo/src/components/script/dom/webidls/HTMLLegendElement.webidl => servo/components/script/dom/webidls/HTMLLegendElement.webidl rename : servo/src/components/script/dom/webidls/HTMLLinkElement.webidl => servo/components/script/dom/webidls/HTMLLinkElement.webidl rename : servo/src/components/script/dom/webidls/HTMLMapElement.webidl => servo/components/script/dom/webidls/HTMLMapElement.webidl rename : servo/src/components/script/dom/webidls/HTMLMediaElement.webidl => servo/components/script/dom/webidls/HTMLMediaElement.webidl rename : servo/src/components/script/dom/webidls/HTMLMetaElement.webidl => servo/components/script/dom/webidls/HTMLMetaElement.webidl rename : servo/src/components/script/dom/webidls/HTMLMeterElement.webidl => servo/components/script/dom/webidls/HTMLMeterElement.webidl rename : servo/src/components/script/dom/webidls/HTMLModElement.webidl => servo/components/script/dom/webidls/HTMLModElement.webidl rename : servo/src/components/script/dom/webidls/HTMLOListElement.webidl => servo/components/script/dom/webidls/HTMLOListElement.webidl rename : servo/src/components/script/dom/webidls/HTMLObjectElement.webidl => servo/components/script/dom/webidls/HTMLObjectElement.webidl rename : servo/src/components/script/dom/webidls/HTMLOptGroupElement.webidl => servo/components/script/dom/webidls/HTMLOptGroupElement.webidl rename : servo/src/components/script/dom/webidls/HTMLOptionElement.webidl => servo/components/script/dom/webidls/HTMLOptionElement.webidl rename : servo/src/components/script/dom/webidls/HTMLOutputElement.webidl => servo/components/script/dom/webidls/HTMLOutputElement.webidl rename : servo/src/components/script/dom/webidls/HTMLParagraphElement.webidl => servo/components/script/dom/webidls/HTMLParagraphElement.webidl rename : servo/src/components/script/dom/webidls/HTMLParamElement.webidl => servo/components/script/dom/webidls/HTMLParamElement.webidl rename : servo/src/components/script/dom/webidls/HTMLPreElement.webidl => servo/components/script/dom/webidls/HTMLPreElement.webidl rename : servo/src/components/script/dom/webidls/HTMLProgressElement.webidl => servo/components/script/dom/webidls/HTMLProgressElement.webidl rename : servo/src/components/script/dom/webidls/HTMLQuoteElement.webidl => servo/components/script/dom/webidls/HTMLQuoteElement.webidl rename : servo/src/components/script/dom/webidls/HTMLScriptElement.webidl => servo/components/script/dom/webidls/HTMLScriptElement.webidl rename : servo/src/components/script/dom/webidls/HTMLSelectElement.webidl => servo/components/script/dom/webidls/HTMLSelectElement.webidl rename : servo/src/components/script/dom/webidls/HTMLSourceElement.webidl => servo/components/script/dom/webidls/HTMLSourceElement.webidl rename : servo/src/components/script/dom/webidls/HTMLSpanElement.webidl => servo/components/script/dom/webidls/HTMLSpanElement.webidl rename : servo/src/components/script/dom/webidls/HTMLStyleElement.webidl => servo/components/script/dom/webidls/HTMLStyleElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableCaptionElement.webidl => servo/components/script/dom/webidls/HTMLTableCaptionElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableCellElement.webidl => servo/components/script/dom/webidls/HTMLTableCellElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableColElement.webidl => servo/components/script/dom/webidls/HTMLTableColElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableDataCellElement.webidl => servo/components/script/dom/webidls/HTMLTableDataCellElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableElement.webidl => servo/components/script/dom/webidls/HTMLTableElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableHeaderCellElement.webidl => servo/components/script/dom/webidls/HTMLTableHeaderCellElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableRowElement.webidl => servo/components/script/dom/webidls/HTMLTableRowElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTableSectionElement.webidl => servo/components/script/dom/webidls/HTMLTableSectionElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTemplateElement.webidl => servo/components/script/dom/webidls/HTMLTemplateElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTextAreaElement.webidl => servo/components/script/dom/webidls/HTMLTextAreaElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTimeElement.webidl => servo/components/script/dom/webidls/HTMLTimeElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTitleElement.webidl => servo/components/script/dom/webidls/HTMLTitleElement.webidl rename : servo/src/components/script/dom/webidls/HTMLTrackElement.webidl => servo/components/script/dom/webidls/HTMLTrackElement.webidl rename : servo/src/components/script/dom/webidls/HTMLUListElement.webidl => servo/components/script/dom/webidls/HTMLUListElement.webidl rename : servo/src/components/script/dom/webidls/HTMLUnknownElement.webidl => servo/components/script/dom/webidls/HTMLUnknownElement.webidl rename : servo/src/components/script/dom/webidls/HTMLVideoElement.webidl => servo/components/script/dom/webidls/HTMLVideoElement.webidl rename : servo/src/components/script/dom/webidls/Location.webidl => servo/components/script/dom/webidls/Location.webidl rename : servo/src/components/script/dom/webidls/MessageEvent.webidl => servo/components/script/dom/webidls/MessageEvent.webidl rename : servo/src/components/script/dom/webidls/MouseEvent.webidl => servo/components/script/dom/webidls/MouseEvent.webidl rename : servo/src/components/script/dom/webidls/NamedNodeMap.webidl => servo/components/script/dom/webidls/NamedNodeMap.webidl rename : servo/src/components/script/dom/webidls/Navigator.webidl => servo/components/script/dom/webidls/Navigator.webidl rename : servo/src/components/script/dom/webidls/Node.webidl => servo/components/script/dom/webidls/Node.webidl rename : servo/src/components/script/dom/webidls/NodeFilter.webidl => servo/components/script/dom/webidls/NodeFilter.webidl rename : servo/src/components/script/dom/webidls/NodeIterator.webidl => servo/components/script/dom/webidls/NodeIterator.webidl rename : servo/src/components/script/dom/webidls/NodeList.webidl => servo/components/script/dom/webidls/NodeList.webidl rename : servo/src/components/script/dom/webidls/ParentNode.webidl => servo/components/script/dom/webidls/ParentNode.webidl rename : servo/src/components/script/dom/webidls/Performance.webidl => servo/components/script/dom/webidls/Performance.webidl rename : servo/src/components/script/dom/webidls/PerformanceTiming.webidl => servo/components/script/dom/webidls/PerformanceTiming.webidl rename : servo/src/components/script/dom/webidls/ProcessingInstruction.webidl => servo/components/script/dom/webidls/ProcessingInstruction.webidl rename : servo/src/components/script/dom/webidls/ProgressEvent.webidl => servo/components/script/dom/webidls/ProgressEvent.webidl rename : servo/src/components/script/dom/webidls/Range.webidl => servo/components/script/dom/webidls/Range.webidl rename : servo/src/components/script/dom/webidls/Screen.webidl => servo/components/script/dom/webidls/Screen.webidl rename : servo/src/components/script/dom/webidls/TestBinding.webidl => servo/components/script/dom/webidls/TestBinding.webidl rename : servo/src/components/script/dom/webidls/Text.webidl => servo/components/script/dom/webidls/Text.webidl rename : servo/src/components/script/dom/webidls/TreeWalker.webidl => servo/components/script/dom/webidls/TreeWalker.webidl rename : servo/src/components/script/dom/webidls/UIEvent.webidl => servo/components/script/dom/webidls/UIEvent.webidl rename : servo/src/components/script/dom/webidls/URLSearchParams.webidl => servo/components/script/dom/webidls/URLSearchParams.webidl rename : servo/src/components/script/dom/webidls/URLUtils.webidl => servo/components/script/dom/webidls/URLUtils.webidl rename : servo/src/components/script/dom/webidls/URLUtilsReadOnly.webidl => servo/components/script/dom/webidls/URLUtilsReadOnly.webidl rename : servo/src/components/script/dom/webidls/ValidityState.webidl => servo/components/script/dom/webidls/ValidityState.webidl rename : servo/src/components/script/dom/webidls/Window.webidl => servo/components/script/dom/webidls/Window.webidl rename : servo/src/components/script/dom/webidls/Worker.webidl => servo/components/script/dom/webidls/Worker.webidl rename : servo/src/components/script/dom/webidls/WorkerGlobalScope.webidl => servo/components/script/dom/webidls/WorkerGlobalScope.webidl rename : servo/src/components/script/dom/webidls/WorkerLocation.webidl => servo/components/script/dom/webidls/WorkerLocation.webidl rename : servo/src/components/script/dom/webidls/WorkerNavigator.webidl => servo/components/script/dom/webidls/WorkerNavigator.webidl rename : servo/src/components/script/dom/webidls/XMLHttpRequest.webidl => servo/components/script/dom/webidls/XMLHttpRequest.webidl rename : servo/src/components/script/dom/webidls/XMLHttpRequestEventTarget.webidl => servo/components/script/dom/webidls/XMLHttpRequestEventTarget.webidl rename : servo/src/components/script/dom/webidls/XMLHttpRequestUpload.webidl => servo/components/script/dom/webidls/XMLHttpRequestUpload.webidl rename : servo/src/components/script/dom/window.rs => servo/components/script/dom/window.rs rename : servo/src/components/script/dom/worker.rs => servo/components/script/dom/worker.rs rename : servo/src/components/script/dom/workerglobalscope.rs => servo/components/script/dom/workerglobalscope.rs rename : servo/src/components/script/dom/workerlocation.rs => servo/components/script/dom/workerlocation.rs rename : servo/src/components/script/dom/workernavigator.rs => servo/components/script/dom/workernavigator.rs rename : servo/src/components/script/dom/xmlhttprequest.rs => servo/components/script/dom/xmlhttprequest.rs rename : servo/src/components/script/dom/xmlhttprequesteventtarget.rs => servo/components/script/dom/xmlhttprequesteventtarget.rs rename : servo/src/components/script/dom/xmlhttprequestupload.rs => servo/components/script/dom/xmlhttprequestupload.rs rename : servo/src/components/script/html/cssparse.rs => servo/components/script/html/cssparse.rs rename : servo/src/components/script/html/hubbub_html_parser.rs => servo/components/script/html/hubbub_html_parser.rs rename : servo/src/components/script/layout_interface.rs => servo/components/script/layout_interface.rs rename : servo/src/components/script/script.rs => servo/components/script/lib.rs rename : servo/src/components/script/page.rs => servo/components/script/page.rs rename : servo/src/components/script/script_task.rs => servo/components/script/script_task.rs rename : servo/src/components/script_traits/script_traits.rs => servo/components/script_traits/lib.rs rename : servo/src/components/style/.gitignore => servo/components/style/.gitignore rename : servo/src/components/style/Mako-0.9.1.zip => servo/components/style/Mako-0.9.1.zip rename : servo/src/components/style/README.md => servo/components/style/README.md rename : servo/src/components/style/errors.rs => servo/components/style/errors.rs rename : servo/src/components/style/font_face.rs => servo/components/style/font_face.rs rename : servo/src/components/style/style.rs => servo/components/style/lib.rs rename : servo/src/components/style/media_queries.rs => servo/components/style/media_queries.rs rename : servo/src/components/style/namespaces.rs => servo/components/style/namespaces.rs rename : servo/src/components/style/node.rs => servo/components/style/node.rs rename : servo/src/components/style/parsing_utils.rs => servo/components/style/parsing_utils.rs rename : servo/src/components/style/properties/common_types.rs => servo/components/style/properties/common_types.rs rename : servo/src/components/style/properties/mod.rs.mako => servo/components/style/properties/mod.rs.mako rename : servo/src/components/style/selector_matching.rs => servo/components/style/selector_matching.rs rename : servo/src/components/style/selectors.rs => servo/components/style/selectors.rs rename : servo/src/components/style/stylesheets.rs => servo/components/style/stylesheets.rs rename : servo/src/components/style/user-agent.css => servo/components/style/user-agent.css rename : servo/src/components/util/atom.rs => servo/components/util/atom.rs rename : servo/src/components/util/cache.rs => servo/components/util/cache.rs rename : servo/src/components/util/debug_utils.rs => servo/components/util/debug_utils.rs rename : servo/src/components/util/geometry.rs => servo/components/util/geometry.rs rename : servo/src/components/util/util.rs => servo/components/util/lib.rs rename : servo/src/components/util/logical_geometry.rs => servo/components/util/logical_geometry.rs rename : servo/src/components/util/memory.rs => servo/components/util/memory.rs rename : servo/src/components/util/namespace.rs => servo/components/util/namespace.rs rename : servo/src/components/util/opts.rs => servo/components/util/opts.rs rename : servo/src/components/util/range.rs => servo/components/util/range.rs rename : servo/src/components/util/smallvec.rs => servo/components/util/smallvec.rs rename : servo/src/components/util/sort.rs => servo/components/util/sort.rs rename : servo/src/components/util/str.rs => servo/components/util/str.rs rename : servo/src/components/util/task.rs => servo/components/util/task.rs rename : servo/src/components/util/time.rs => servo/components/util/time.rs rename : servo/src/components/util/vec.rs => servo/components/util/vec.rs rename : servo/src/components/util/workqueue.rs => servo/components/util/workqueue.rs rename : servo/src/test/ci/fontconfig/30-metric-aliases.conf => servo/etc/ci/fontconfig/30-metric-aliases.conf rename : servo/src/test/ci/fontconfig/40-nonlatin.conf => servo/etc/ci/fontconfig/40-nonlatin.conf rename : servo/src/test/ci/fontconfig/45-latin.conf => servo/etc/ci/fontconfig/45-latin.conf rename : servo/src/test/ci/fontconfig/53-monospace-lcd-filter.conf => servo/etc/ci/fontconfig/53-monospace-lcd-filter.conf rename : servo/src/test/ci/xorg.conf => servo/etc/ci/xorg.conf rename : servo/src/etc/doc.servo.org/CNAME => servo/etc/doc.servo.org/CNAME rename : servo/src/etc/doc.servo.org/LICENSE => servo/etc/doc.servo.org/LICENSE rename : servo/src/etc/doc.servo.org/README.md => servo/etc/doc.servo.org/README.md rename : servo/src/etc/doc.servo.org/index.html => servo/etc/doc.servo.org/index.html rename : servo/src/etc/jsdefine => servo/etc/jsdefine rename : servo/src/etc/patches/README => servo/etc/patches/README rename : servo/src/etc/patches/mozjs-stack-bounds.diff => servo/etc/patches/mozjs-stack-bounds.diff rename : servo/src/etc/rustdoc-style.html => servo/etc/rustdoc-style.html rename : servo/src/etc/servo.sb => servo/etc/servo.sb rename : servo/src/etc/servo_gdb.py => servo/etc/servo_gdb.py rename : servo/src/components/embedding/README.md => servo/ports/cef/README.md rename : servo/src/components/embedding/browser.rs => servo/ports/cef/browser.rs rename : servo/src/components/embedding/command_line.rs => servo/ports/cef/command_line.rs rename : servo/src/components/embedding/core.rs => servo/ports/cef/core.rs rename : servo/src/components/embedding/eutil.rs => servo/ports/cef/eutil.rs rename : servo/src/components/embedding/embedding.rs => servo/ports/cef/lib.rs rename : servo/src/components/embedding/mem.rs => servo/ports/cef/mem.rs rename : servo/src/components/embedding/request.rs => servo/ports/cef/request.rs rename : servo/src/components/embedding/string.rs => servo/ports/cef/string.rs rename : servo/src/components/embedding/task.rs => servo/ports/cef/task.rs rename : servo/src/components/embedding/types.rs => servo/ports/cef/types.rs rename : servo/src/components/embedding/urlrequest.rs => servo/ports/cef/urlrequest.rs rename : servo/src/etc/licenseck.py => servo/python/licenseck.py rename : servo/src/components/main/servo.rs => servo/src/lib.rs rename : servo/src/platform/macos/rust-task_info/Makefile.in => servo/support/rust-task_info/Makefile.in rename : servo/src/platform/macos/rust-task_info/task_info.rc => servo/support/rust-task_info/src/lib.rs rename : servo/src/platform/macos/rust-task_info/task_basic_info.rs => servo/support/rust-task_info/src/task_basic_info.rs rename : servo/src/platform/macos/rust-task_info/task_info.c => servo/support/rust-task_info/src/task_info.c rename : servo/src/test/content/harness.js => servo/tests/content/harness.js rename : servo/src/test/content/test.jpg => servo/tests/content/test.jpg rename : servo/src/test/content/test.png => servo/tests/content/test.png rename : servo/src/test/content/test_DOMParser.html => servo/tests/content/test_DOMParser.html rename : servo/src/test/content/test_Event.html => servo/tests/content/test_Event.html rename : servo/src/test/content/test_MouseEvent.html => servo/tests/content/test_MouseEvent.html rename : servo/src/test/content/test_body_listener.html => servo/tests/content/test_body_listener.html rename : servo/src/test/content/test_caption.html => servo/tests/content/test_caption.html rename : servo/src/test/content/test_click_prevent.html => servo/tests/content/test_click_prevent.html rename : servo/src/test/content/test_collections.html => servo/tests/content/test_collections.html rename : servo/src/test/content/test_create_element.html => servo/tests/content/test_create_element.html rename : servo/src/test/content/test_documentElement.html => servo/tests/content/test_documentElement.html rename : servo/src/test/content/test_document_adoptNode.html => servo/tests/content/test_document_adoptNode.html rename : servo/src/test/content/test_document_body.html => servo/tests/content/test_document_body.html rename : servo/src/test/content/test_document_characterSet.html => servo/tests/content/test_document_characterSet.html rename : servo/src/test/content/test_document_characterSet_default.html => servo/tests/content/test_document_characterSet_default.html rename : servo/src/test/content/test_document_characterSet_invalid.html => servo/tests/content/test_document_characterSet_invalid.html rename : servo/src/test/content/test_document_characterSet_long.html => servo/tests/content/test_document_characterSet_long.html rename : servo/src/test/content/test_document_characterSet_short.html => servo/tests/content/test_document_characterSet_short.html rename : servo/src/test/content/test_document_compatMode.html => servo/tests/content/test_document_compatMode.html rename : servo/src/test/content/test_document_compatMode_loose.html => servo/tests/content/test_document_compatMode_loose.html rename : servo/src/test/content/test_document_compatMode_strict.html => servo/tests/content/test_document_compatMode_strict.html rename : servo/src/test/content/test_document_contenttype.html => servo/tests/content/test_document_contenttype.html rename : servo/src/test/content/test_document_datalist_options.html => servo/tests/content/test_document_datalist_options.html rename : servo/src/test/content/test_document_getElementById.html => servo/tests/content/test_document_getElementById.html rename : servo/src/test/content/test_document_getElementsByName.html => servo/tests/content/test_document_getElementsByName.html rename : servo/src/test/content/test_document_head.html => servo/tests/content/test_document_head.html rename : servo/src/test/content/test_document_implementation.html => servo/tests/content/test_document_implementation.html rename : servo/src/test/content/test_document_links_cache.html => servo/tests/content/test_document_links_cache.html rename : servo/src/test/content/test_document_set_node_value.html => servo/tests/content/test_document_set_node_value.html rename : servo/src/test/content/test_document_title_nontextchildren.html => servo/tests/content/test_document_title_nontextchildren.html rename : servo/src/test/content/test_document_url.html => servo/tests/content/test_document_url.html rename : servo/src/test/content/test_domtokenlist.html => servo/tests/content/test_domtokenlist.html rename : servo/src/test/content/test_element_attribute.html => servo/tests/content/test_element_attribute.html rename : servo/src/test/content/test_element_attributes.html => servo/tests/content/test_element_attributes.html rename : servo/src/test/content/test_element_classList.html => servo/tests/content/test_element_classList.html rename : servo/src/test/content/test_element_className.html => servo/tests/content/test_element_className.html rename : servo/src/test/content/test_element_matches.html => servo/tests/content/test_element_matches.html rename : servo/src/test/content/test_empty_clientrect.html => servo/tests/content/test_empty_clientrect.html rename : servo/src/test/content/test_enabled_disabled_selectors.html => servo/tests/content/test_enabled_disabled_selectors.html rename : servo/src/test/content/test_event_dispatch.html => servo/tests/content/test_event_dispatch.html rename : servo/src/test/content/test_event_dispatch_dynamic.html => servo/tests/content/test_event_dispatch_dynamic.html rename : servo/src/test/content/test_event_dispatch_order.html => servo/tests/content/test_event_dispatch_order.html rename : servo/src/test/content/test_event_handler_syntax_error.html => servo/tests/content/test_event_handler_syntax_error.html rename : servo/src/test/content/test_event_listener.html => servo/tests/content/test_event_listener.html rename : servo/src/test/content/test_getBoundingClientRect.html => servo/tests/content/test_getBoundingClientRect.html rename : servo/src/test/content/test_global.html => servo/tests/content/test_global.html rename : servo/src/test/content/test_htmlcollection.html => servo/tests/content/test_htmlcollection.html rename : servo/src/test/content/test_htmlfieldsetelement_elements.html => servo/tests/content/test_htmlfieldsetelement_elements.html rename : servo/src/test/content/test_htmlspacechars.html => servo/tests/content/test_htmlspacechars.html rename : servo/src/test/content/test_img_width_height.html => servo/tests/content/test_img_width_height.html rename : servo/src/test/content/test_inline_event_handler.html => servo/tests/content/test_inline_event_handler.html rename : servo/src/test/content/test_innerHTML.html => servo/tests/content/test_innerHTML.html rename : servo/src/test/content/test_interfaces.html => servo/tests/content/test_interfaces.html rename : servo/src/test/content/test_load_event.html => servo/tests/content/test_load_event.html rename : servo/src/test/content/test_navigator.html => servo/tests/content/test_navigator.html rename : servo/src/test/content/test_node_cloneNode.html => servo/tests/content/test_node_cloneNode.html rename : servo/src/test/content/test_node_compareDocumentPosition.html => servo/tests/content/test_node_compareDocumentPosition.html rename : servo/src/test/content/test_node_contains.html => servo/tests/content/test_node_contains.html rename : servo/src/test/content/test_node_insertBefore.html => servo/tests/content/test_node_insertBefore.html rename : servo/src/test/content/test_node_isEqualNode.html => servo/tests/content/test_node_isEqualNode.html rename : servo/src/test/content/test_node_normalize.html => servo/tests/content/test_node_normalize.html rename : servo/src/test/content/test_node_replaceChild.html => servo/tests/content/test_node_replaceChild.html rename : servo/src/test/content/test_parentNode_querySelector.html => servo/tests/content/test_parentNode_querySelector.html rename : servo/src/test/content/test_parentNode_querySelectorAll.html => servo/tests/content/test_parentNode_querySelectorAll.html rename : servo/src/test/content/test_parentnodes.html => servo/tests/content/test_parentnodes.html rename : servo/src/test/content/test_prototypes.html => servo/tests/content/test_prototypes.html rename : servo/src/test/content/test_proxy_setter.html => servo/tests/content/test_proxy_setter.html rename : servo/src/test/content/test_script_src_attribute.html => servo/tests/content/test_script_src_attribute.html rename : servo/src/test/content/test_script_type.html => servo/tests/content/test_script_type.html rename : servo/src/test/content/test_textcontent.html => servo/tests/content/test_textcontent.html rename : servo/src/test/content/test_title.html => servo/tests/content/test_title.html rename : servo/src/test/content/test_trace_null.html => servo/tests/content/test_trace_null.html rename : servo/src/test/content/test_union.html => servo/tests/content/test_union.html rename : servo/src/test/content/test_window.html => servo/tests/content/test_window.html rename : servo/src/test/content/test_window_performance.html => servo/tests/content/test_window_performance.html rename : servo/src/test/content/test_window_setInterval.html => servo/tests/content/test_window_setInterval.html rename : servo/src/test/harness/contenttest/contenttest.rs => servo/tests/contenttest.rs rename : servo/src/test/html/about-mozilla.html => servo/tests/html/about-mozilla.html rename : servo/src/test/html/acid1.html => servo/tests/html/acid1.html rename : servo/src/test/html/acid2.html => servo/tests/html/acid2.html rename : servo/src/test/html/andreas.jpeg => servo/tests/html/andreas.jpeg rename : servo/src/test/html/anonymous_table.html => servo/tests/html/anonymous_table.html rename : servo/src/test/html/background.html => servo/tests/html/background.html rename : servo/src/test/html/bad-line-ends.html => servo/tests/html/bad-line-ends.html rename : servo/src/test/html/box-model-smoketest.html => servo/tests/html/box-model-smoketest.html rename : servo/src/test/html/color-change-text.html => servo/tests/html/color-change-text.html rename : servo/src/test/html/combining-character-sequences.html => servo/tests/html/combining-character-sequences.html rename : servo/src/test/html/demo.css => servo/tests/html/demo.css rename : servo/src/test/html/demo.html => servo/tests/html/demo.html rename : servo/src/test/html/doge-servo.html => servo/tests/html/doge-servo.html rename : servo/src/test/html/doge-servo.jpg => servo/tests/html/doge-servo.jpg rename : servo/src/test/html/failure.html => servo/tests/html/failure.html rename : servo/src/test/html/filmstrip.html => servo/tests/html/filmstrip.html rename : servo/src/test/html/fixed_table.html => servo/tests/html/fixed_table.html rename : servo/src/test/html/fixed_table_2.html => servo/tests/html/fixed_table_2.html rename : servo/src/test/html/fixed_table_additional_cols.html => servo/tests/html/fixed_table_additional_cols.html rename : servo/src/test/html/fixed_table_basic_height.html => servo/tests/html/fixed_table_basic_height.html rename : servo/src/test/html/fixed_table_simple.html => servo/tests/html/fixed_table_simple.html rename : servo/src/test/html/fixed_table_with_margin_padding.html => servo/tests/html/fixed_table_with_margin_padding.html rename : servo/src/test/html/head_link_test.html => servo/tests/html/head_link_test.html rename : servo/src/test/html/hello.html => servo/tests/html/hello.html rename : servo/src/test/html/https.html => servo/tests/html/https.html rename : servo/src/test/html/ib-split-image.html => servo/tests/html/ib-split-image.html rename : servo/src/test/html/inline-block-split-2.html => servo/tests/html/inline-block-split-2.html rename : servo/src/test/html/inline-block-split-3.html => servo/tests/html/inline-block-split-3.html rename : servo/src/test/html/inline-block-split-float.html => servo/tests/html/inline-block-split-float.html rename : servo/src/test/html/inline-block-split.html => servo/tests/html/inline-block-split.html rename : servo/src/test/html/inline_bg_color_simple.html => servo/tests/html/inline_bg_color_simple.html rename : servo/src/test/html/itried.jpg => servo/tests/html/itried.jpg rename : servo/src/test/html/ligatures.html => servo/tests/html/ligatures.html rename : servo/src/test/html/lineheight-simple.css => servo/tests/html/lineheight-simple.css rename : servo/src/test/html/lineheight-simple.html => servo/tests/html/lineheight-simple.html rename : servo/src/test/html/lipsum.html => servo/tests/html/lipsum.html rename : servo/src/test/html/longcat.html => servo/tests/html/longcat.html rename : servo/src/test/html/longcatbot.png => servo/tests/html/longcatbot.png rename : servo/src/test/html/longcatmid.png => servo/tests/html/longcatmid.png rename : servo/src/test/html/longcattop.png => servo/tests/html/longcattop.png rename : servo/src/test/html/lots_of_background_colors.css => servo/tests/html/lots_of_background_colors.css rename : servo/src/test/html/mojira.html => servo/tests/html/mojira.html rename : servo/src/test/html/object_element.html => servo/tests/html/object_element.html rename : servo/src/test/html/perf-rainbow-hard.html => servo/tests/html/perf-rainbow-hard.html rename : servo/src/test/html/perf-rainbow.html => servo/tests/html/perf-rainbow.html rename : servo/src/test/html/rust-0.png => servo/tests/html/rust-0.png rename : servo/src/test/html/rust-135.png => servo/tests/html/rust-135.png rename : servo/src/test/html/rust-180.png => servo/tests/html/rust-180.png rename : servo/src/test/html/rust-225.png => servo/tests/html/rust-225.png rename : servo/src/test/html/rust-270.png => servo/tests/html/rust-270.png rename : servo/src/test/html/rust-315.png => servo/tests/html/rust-315.png rename : servo/src/test/html/rust-45.png => servo/tests/html/rust-45.png rename : servo/src/test/html/rust-90.png => servo/tests/html/rust-90.png rename : servo/src/test/html/small-layout-test.html => servo/tests/html/small-layout-test.html rename : servo/src/test/html/small_color_test.css => servo/tests/html/small_color_test.css rename : servo/src/test/html/small_color_test.html => servo/tests/html/small_color_test.html rename : servo/src/test/html/summit-crash.html => servo/tests/html/summit-crash.html rename : servo/src/test/html/summit-fail.html => servo/tests/html/summit-fail.html rename : servo/src/test/html/summit-one.html => servo/tests/html/summit-one.html rename : servo/src/test/html/summit-three.html => servo/tests/html/summit-three.html rename : servo/src/test/html/summit-two.html => servo/tests/html/summit-two.html rename : servo/src/test/html/summit2.html => servo/tests/html/summit2.html rename : servo/src/test/html/summit3.html => servo/tests/html/summit3.html rename : servo/src/test/html/test-absolute.css => servo/tests/html/test-absolute.css rename : servo/src/test/html/test-absolute.html => servo/tests/html/test-absolute.html rename : servo/src/test/html/test-css-pseudo-root.html => servo/tests/html/test-css-pseudo-root.html rename : servo/src/test/html/test-inline.html => servo/tests/html/test-inline.html rename : servo/src/test/html/test-js-alert.html => servo/tests/html/test-js-alert.html rename : servo/src/test/html/test-js-console.html => servo/tests/html/test-js-console.html rename : servo/src/test/html/test-js-image.html => servo/tests/html/test-js-image.html rename : servo/src/test/html/test-js.html => servo/tests/html/test-js.html rename : servo/src/test/html/test-lineheight-verticalalign.html => servo/tests/html/test-lineheight-verticalalign.html rename : servo/src/test/html/test-many-images-different.html => servo/tests/html/test-many-images-different.html rename : servo/src/test/html/test-many-images.html => servo/tests/html/test-many-images.html rename : servo/src/test/html/test-text-break.html => servo/tests/html/test-text-break.html rename : servo/src/test/html/test-text.html => servo/tests/html/test-text.html rename : servo/src/test/html/test.css => servo/tests/html/test.css rename : servo/src/test/html/test.html => servo/tests/html/test.html rename : servo/src/test/html/test.js => servo/tests/html/test.js rename : servo/src/test/html/test_UIEvent_resize.html => servo/tests/html/test_UIEvent_resize.html rename : servo/src/test/html/test_bg_color.html => servo/tests/html/test_bg_color.html rename : servo/src/test/html/test_bg_color_simple.css => servo/tests/html/test_bg_color_simple.css rename : servo/src/test/html/test_bg_color_simple.html => servo/tests/html/test_bg_color_simple.html rename : servo/src/test/html/test_border.html => servo/tests/html/test_border.html rename : servo/src/test/html/test_canvas.html => servo/tests/html/test_canvas.html rename : servo/src/test/html/test_class_helloworld.html => servo/tests/html/test_class_helloworld.html rename : servo/src/test/html/test_clear.html => servo/tests/html/test_clear.html rename : servo/src/test/html/test_clear_float.html => servo/tests/html/test_clear_float.html rename : servo/src/test/html/test_close.html => servo/tests/html/test_close.html rename : servo/src/test/html/test_cssunit_length.html => servo/tests/html/test_cssunit_length.html rename : servo/src/test/html/test_float_placement.html => servo/tests/html/test_float_placement.html rename : servo/src/test/html/test_getter_time.html => servo/tests/html/test_getter_time.html rename : servo/src/test/html/test_hammer_layout.css => servo/tests/html/test_hammer_layout.css rename : servo/src/test/html/test_hammer_layout.html => servo/tests/html/test_hammer_layout.html rename : servo/src/test/html/test_inline_border.html => servo/tests/html/test_inline_border.html rename : servo/src/test/html/test_inline_boxes.html => servo/tests/html/test_inline_boxes.html rename : servo/src/test/html/test_interval.html => servo/tests/html/test_interval.html rename : servo/src/test/html/test_italic_bold.html => servo/tests/html/test_italic_bold.html rename : servo/src/test/html/test_linking.css => servo/tests/html/test_linking.css rename : servo/src/test/html/test_local_bookmark.html => servo/tests/html/test_local_bookmark.html rename : servo/src/test/html/test_overflow_hidden.html => servo/tests/html/test_overflow_hidden.html rename : servo/src/test/html/test_pseudo.html => servo/tests/html/test_pseudo.html rename : servo/src/test/html/test_sandboxed.html => servo/tests/html/test_sandboxed.html rename : servo/src/test/html/test_sandboxed_iframe.html => servo/tests/html/test_sandboxed_iframe.html rename : servo/src/test/html/test_slam_layout.css => servo/tests/html/test_slam_layout.css rename : servo/src/test/html/test_slam_layout.html => servo/tests/html/test_slam_layout.html rename : servo/src/test/html/test_timeout.html => servo/tests/html/test_timeout.html rename : servo/src/test/html/test_underline.html => servo/tests/html/test_underline.html rename : servo/src/test/html/test_underline_helloworld.html => servo/tests/html/test_underline_helloworld.html rename : servo/src/test/html/text_deco_simple.html => servo/tests/html/text_deco_simple.html rename : servo/src/test/html/tiny_test.html => servo/tests/html/tiny_test.html rename : servo/src/test/html/vertical_align_simple.html => servo/tests/html/vertical_align_simple.html rename : servo/src/test/power/PowerMeasure.py => servo/tests/power/PowerMeasure.py rename : servo/src/test/power/README.md => servo/tests/power/README.md rename : servo/src/test/harness/reftest/reftest.rs => servo/tests/reftest.rs
		
			
				
	
	
		
			5788 lines
		
	
	
	
		
			234 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			5788 lines
		
	
	
	
		
			234 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# 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/.
 | 
						|
 | 
						|
# Common codegen classes.
 | 
						|
 | 
						|
import os
 | 
						|
import string
 | 
						|
import operator
 | 
						|
 | 
						|
from WebIDL import *
 | 
						|
from Configuration import NoSuchDescriptorError
 | 
						|
 | 
						|
AUTOGENERATED_WARNING_COMMENT = \
 | 
						|
    "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
 | 
						|
ADDPROPERTY_HOOK_NAME = '_addProperty'
 | 
						|
FINALIZE_HOOK_NAME = '_finalize'
 | 
						|
TRACE_HOOK_NAME = '_trace'
 | 
						|
CONSTRUCT_HOOK_NAME = '_constructor'
 | 
						|
HASINSTANCE_HOOK_NAME = '_hasInstance'
 | 
						|
 | 
						|
def replaceFileIfChanged(filename, newContents):
 | 
						|
    """
 | 
						|
    Read a copy of the old file, so that we don't touch it if it hasn't changed.
 | 
						|
    Returns True if the file was updated, false otherwise.
 | 
						|
    """
 | 
						|
    oldFileContents = ""
 | 
						|
    try:
 | 
						|
        oldFile = open(filename, 'rb')
 | 
						|
        oldFileContents = ''.join(oldFile.readlines())
 | 
						|
        oldFile.close()
 | 
						|
    except:
 | 
						|
        pass
 | 
						|
 | 
						|
    if newContents == oldFileContents:
 | 
						|
        return False
 | 
						|
 | 
						|
    f = open(filename, 'wb')
 | 
						|
    f.write(newContents)
 | 
						|
    f.close()
 | 
						|
 | 
						|
def toStringBool(arg):
 | 
						|
    return str(not not arg).lower()
 | 
						|
 | 
						|
def toBindingNamespace(arg):
 | 
						|
    return re.sub("((_workers)?$)", "Binding\\1", arg);
 | 
						|
 | 
						|
class CGThing():
 | 
						|
    """
 | 
						|
    Abstract base class for things that spit out code.
 | 
						|
    """
 | 
						|
    def __init__(self):
 | 
						|
        pass # Nothing for now
 | 
						|
    def declare(self):
 | 
						|
        """Produce code for a header file."""
 | 
						|
        assert(False)  # Override me!
 | 
						|
    def define(self):
 | 
						|
        """Produce code for a cpp file."""
 | 
						|
        assert(False) # Override me!
 | 
						|
 | 
						|
class CGNativePropertyHooks(CGThing):
 | 
						|
    """
 | 
						|
    Generate a NativePropertyHooks for a given descriptor
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def declare(self):
 | 
						|
        if self.descriptor.workers:
 | 
						|
            return ""
 | 
						|
        return "extern const NativePropertyHooks NativeHooks;\n"
 | 
						|
    def define(self):
 | 
						|
        if self.descriptor.workers:
 | 
						|
            return ""
 | 
						|
        if self.descriptor.concrete and self.descriptor.proxy:
 | 
						|
            resolveOwnProperty = "ResolveOwnProperty"
 | 
						|
            enumerateOwnProperties = "EnumerateOwnProperties"
 | 
						|
        else:
 | 
						|
            enumerateOwnProperties = resolveOwnProperty = "NULL"
 | 
						|
        parent = self.descriptor.interface.parent
 | 
						|
        parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::NativeHooks"
 | 
						|
                       if parent else 'NULL')
 | 
						|
        return """
 | 
						|
const NativePropertyHooks NativeHooks = { %s, ResolveProperty, %s, EnumerateProperties, %s };
 | 
						|
""" % (resolveOwnProperty, enumerateOwnProperties, parentHooks)
 | 
						|
 | 
						|
def DOMClass(descriptor):
 | 
						|
        protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain]
 | 
						|
        # Pad out the list to the right length with _ID_Count so we
 | 
						|
        # guarantee that all the lists are the same length.  _ID_Count
 | 
						|
        # is never the ID of any prototype, so it's safe to use as
 | 
						|
        # padding.
 | 
						|
        protoList.extend(['prototypes::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList)))
 | 
						|
        prototypeChainString = ', '.join(protoList)
 | 
						|
        nativeHooks = "NULL" if descriptor.workers else "&NativeHooks"
 | 
						|
        return """{
 | 
						|
  { %s },
 | 
						|
  %s, %s
 | 
						|
}""" % (prototypeChainString, toStringBool(descriptor.nativeIsISupports),
 | 
						|
          nativeHooks)
 | 
						|
 | 
						|
class CGDOMJSClass(CGThing):
 | 
						|
    """
 | 
						|
    Generate a DOMJSClass for a given descriptor
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def declare(self):
 | 
						|
        return "extern DOMJSClass Class;\n"
 | 
						|
    def define(self):
 | 
						|
        traceHook = TRACE_HOOK_NAME if self.descriptor.customTrace else 'NULL'
 | 
						|
        return """
 | 
						|
DOMJSClass Class = {
 | 
						|
  { "%s",
 | 
						|
    JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
 | 
						|
    %s, /* addProperty */
 | 
						|
    JS_PropertyStub,       /* delProperty */
 | 
						|
    JS_PropertyStub,       /* getProperty */
 | 
						|
    JS_StrictPropertyStub, /* setProperty */
 | 
						|
    JS_EnumerateStub,
 | 
						|
    JS_ResolveStub,
 | 
						|
    JS_ConvertStub,
 | 
						|
    %s, /* finalize */
 | 
						|
    NULL,                  /* checkAccess */
 | 
						|
    NULL,                  /* call */
 | 
						|
    NULL,                  /* hasInstance */
 | 
						|
    NULL,                  /* construct */
 | 
						|
    %s, /* trace */
 | 
						|
    JSCLASS_NO_INTERNAL_MEMBERS
 | 
						|
  },
 | 
						|
  %s
 | 
						|
};
 | 
						|
""" % (self.descriptor.interface.identifier.name,
 | 
						|
       ADDPROPERTY_HOOK_NAME if self.descriptor.concrete and not self.descriptor.workers and self.descriptor.wrapperCache else 'JS_PropertyStub',
 | 
						|
       FINALIZE_HOOK_NAME, traceHook,
 | 
						|
       CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
 | 
						|
 | 
						|
class CGPrototypeJSClass(CGThing):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def declare(self):
 | 
						|
        # We're purely for internal consumption
 | 
						|
        return ""
 | 
						|
    def define(self):
 | 
						|
        return """static JSClass PrototypeClass = {
 | 
						|
  "%sPrototype",
 | 
						|
  JSCLASS_HAS_RESERVED_SLOTS(1),
 | 
						|
  JS_PropertyStub,       /* addProperty */
 | 
						|
  JS_PropertyStub,       /* delProperty */
 | 
						|
  JS_PropertyStub,       /* getProperty */
 | 
						|
  JS_StrictPropertyStub, /* setProperty */
 | 
						|
  JS_EnumerateStub,
 | 
						|
  JS_ResolveStub,
 | 
						|
  JS_ConvertStub,
 | 
						|
  NULL,                  /* finalize */
 | 
						|
  NULL,                  /* checkAccess */
 | 
						|
  NULL,                  /* call */
 | 
						|
  NULL,                  /* hasInstance */
 | 
						|
  NULL,                  /* construct */
 | 
						|
  NULL,                  /* trace */
 | 
						|
  JSCLASS_NO_INTERNAL_MEMBERS
 | 
						|
};
 | 
						|
""" % (self.descriptor.interface.identifier.name)
 | 
						|
 | 
						|
class CGInterfaceObjectJSClass(CGThing):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def declare(self):
 | 
						|
        # We're purely for internal consumption
 | 
						|
        return ""
 | 
						|
    def define(self):
 | 
						|
        if not self.descriptor.hasInstanceInterface:
 | 
						|
            return ""
 | 
						|
        ctorname = "NULL" if not self.descriptor.interface.ctor() else CONSTRUCT_HOOK_NAME
 | 
						|
        hasinstance = HASINSTANCE_HOOK_NAME
 | 
						|
        return """
 | 
						|
static JSClass InterfaceObjectClass = {
 | 
						|
  "Function", 0,
 | 
						|
  JS_PropertyStub,       /* addProperty */
 | 
						|
  JS_PropertyStub,       /* delProperty */
 | 
						|
  JS_PropertyStub,       /* getProperty */
 | 
						|
  JS_StrictPropertyStub, /* setProperty */
 | 
						|
  JS_EnumerateStub,
 | 
						|
  JS_ResolveStub,
 | 
						|
  JS_ConvertStub,
 | 
						|
  NULL,                  /* finalize */
 | 
						|
  NULL,                  /* checkAccess */
 | 
						|
  %s, /* call */
 | 
						|
  %s, /* hasInstance */
 | 
						|
  %s, /* construct */
 | 
						|
  NULL,                  /* trace */
 | 
						|
  JSCLASS_NO_INTERNAL_MEMBERS
 | 
						|
};
 | 
						|
""" % (ctorname, hasinstance, ctorname)
 | 
						|
 | 
						|
class CGList(CGThing):
 | 
						|
    """
 | 
						|
    Generate code for a list of GCThings.  Just concatenates them together, with
 | 
						|
    an optional joiner string.  "\n" is a common joiner.
 | 
						|
    """
 | 
						|
    def __init__(self, children, joiner=""):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.children = children
 | 
						|
        self.joiner = joiner
 | 
						|
    def append(self, child):
 | 
						|
        self.children.append(child)
 | 
						|
    def prepend(self, child):
 | 
						|
        self.children.insert(0, child)
 | 
						|
    def join(self, generator):
 | 
						|
        return self.joiner.join(filter(lambda s: len(s) > 0, (child for child in generator)))
 | 
						|
    def declare(self):
 | 
						|
        return self.join(child.declare() for child in self.children if child is not None)
 | 
						|
    def define(self):
 | 
						|
        return self.join(child.define() for child in self.children if child is not None)
 | 
						|
 | 
						|
class CGGeneric(CGThing):
 | 
						|
    """
 | 
						|
    A class that spits out a fixed string into the codegen.  Can spit out a
 | 
						|
    separate string for the declaration too.
 | 
						|
    """
 | 
						|
    def __init__(self, define="", declare=""):
 | 
						|
        self.declareText = declare
 | 
						|
        self.defineText = define
 | 
						|
    def declare(self):
 | 
						|
        return self.declareText
 | 
						|
    def define(self):
 | 
						|
        return self.defineText
 | 
						|
 | 
						|
# We'll want to insert the indent at the beginnings of lines, but we
 | 
						|
# don't want to indent empty lines.  So only indent lines that have a
 | 
						|
# non-newline character on them.
 | 
						|
lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)
 | 
						|
class CGIndenter(CGThing):
 | 
						|
    """
 | 
						|
    A class that takes another CGThing and generates code that indents that
 | 
						|
    CGThing by some number of spaces.  The default indent is two spaces.
 | 
						|
    """
 | 
						|
    def __init__(self, child, indentLevel=2, declareOnly=False):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.child = child
 | 
						|
        self.indent = " " * indentLevel
 | 
						|
        self.declareOnly = declareOnly
 | 
						|
    def declare(self):
 | 
						|
        decl = self.child.declare()
 | 
						|
        if decl is not "":
 | 
						|
            return re.sub(lineStartDetector, self.indent, decl)
 | 
						|
        else:
 | 
						|
            return ""
 | 
						|
    def define(self):
 | 
						|
        defn = self.child.define()
 | 
						|
        if defn is not "" and not self.declareOnly:
 | 
						|
            return re.sub(lineStartDetector, self.indent, defn)
 | 
						|
        else:
 | 
						|
            return defn
 | 
						|
 | 
						|
class CGWrapper(CGThing):
 | 
						|
    """
 | 
						|
    Generic CGThing that wraps other CGThings with pre and post text.
 | 
						|
    """
 | 
						|
    def __init__(self, child, pre="", post="", declarePre=None,
 | 
						|
                 declarePost=None, definePre=None, definePost=None,
 | 
						|
                 declareOnly=False, defineOnly=False, reindent=False):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.child = child
 | 
						|
        self.declarePre = declarePre or pre
 | 
						|
        self.declarePost = declarePost or post
 | 
						|
        self.definePre = definePre or pre
 | 
						|
        self.definePost = definePost or post
 | 
						|
        self.declareOnly = declareOnly
 | 
						|
        self.defineOnly = defineOnly
 | 
						|
        self.reindent = reindent
 | 
						|
    def declare(self):
 | 
						|
        if self.defineOnly:
 | 
						|
            return ''
 | 
						|
        decl = self.child.declare()
 | 
						|
        if self.reindent:
 | 
						|
            # We don't use lineStartDetector because we don't want to
 | 
						|
            # insert whitespace at the beginning of our _first_ line.
 | 
						|
            decl = stripTrailingWhitespace(
 | 
						|
                decl.replace("\n", "\n" + (" " * len(self.declarePre))))
 | 
						|
        return self.declarePre + decl + self.declarePost
 | 
						|
    def define(self):
 | 
						|
        if self.declareOnly:
 | 
						|
            return ''
 | 
						|
        defn = self.child.define()
 | 
						|
        if self.reindent:
 | 
						|
            # We don't use lineStartDetector because we don't want to
 | 
						|
            # insert whitespace at the beginning of our _first_ line.
 | 
						|
            defn = stripTrailingWhitespace(
 | 
						|
                defn.replace("\n", "\n" + (" " * len(self.definePre))))
 | 
						|
        return self.definePre + defn + self.definePost
 | 
						|
 | 
						|
class CGIfWrapper(CGWrapper):
 | 
						|
    def __init__(self, child, condition):
 | 
						|
        pre = CGWrapper(CGGeneric(condition), pre="if (", post=") {\n",
 | 
						|
                        reindent=True)
 | 
						|
        CGWrapper.__init__(self, CGIndenter(child), pre=pre.define(),
 | 
						|
                           post="\n}")
 | 
						|
 | 
						|
class CGNamespace(CGWrapper):
 | 
						|
    def __init__(self, namespace, child, declareOnly=False):
 | 
						|
        pre = "namespace %s {\n" % namespace
 | 
						|
        post = "} // namespace %s\n" % namespace
 | 
						|
        CGWrapper.__init__(self, child, pre=pre, post=post,
 | 
						|
                           declareOnly=declareOnly)
 | 
						|
    @staticmethod
 | 
						|
    def build(namespaces, child, declareOnly=False):
 | 
						|
        """
 | 
						|
        Static helper method to build multiple wrapped namespaces.
 | 
						|
        """
 | 
						|
        if not namespaces:
 | 
						|
            return CGWrapper(child, declareOnly=declareOnly)
 | 
						|
        inner = CGNamespace.build(namespaces[1:], child, declareOnly=declareOnly)
 | 
						|
        return CGNamespace(namespaces[0], inner, declareOnly=declareOnly)
 | 
						|
 | 
						|
class CGIncludeGuard(CGWrapper):
 | 
						|
    """
 | 
						|
    Generates include guards for a header.
 | 
						|
    """
 | 
						|
    def __init__(self, prefix, child):
 | 
						|
        """|prefix| is the filename without the extension."""
 | 
						|
        define = 'mozilla_dom_%s_h__' % prefix
 | 
						|
        CGWrapper.__init__(self, child,
 | 
						|
                           declarePre='#ifndef %s\n#define %s\n\n' % (define, define),
 | 
						|
                           declarePost='\n#endif // %s\n' % define)
 | 
						|
 | 
						|
def getTypes(descriptor):
 | 
						|
    """
 | 
						|
    Get all argument and return types for all members of the descriptor
 | 
						|
    """
 | 
						|
    members = [m for m in descriptor.interface.members]
 | 
						|
    if descriptor.interface.ctor():
 | 
						|
        members.append(descriptor.interface.ctor())
 | 
						|
    signatures = [s for m in members if m.isMethod() for s in m.signatures()]
 | 
						|
    types = []
 | 
						|
    for s in signatures:
 | 
						|
        assert len(s) == 2
 | 
						|
        (returnType, arguments) = s
 | 
						|
        types.append(returnType)
 | 
						|
        types.extend([a.type for a in arguments])
 | 
						|
 | 
						|
    types.extend(a.type for a in members if a.isAttr())
 | 
						|
    return types
 | 
						|
 | 
						|
class CGHeaders(CGWrapper):
 | 
						|
    """
 | 
						|
    Generates the appropriate include statements.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptors, dictionaries, declareIncludes,
 | 
						|
                 defineIncludes, child):
 | 
						|
        """
 | 
						|
        Builds a set of includes to cover |descriptors|.
 | 
						|
 | 
						|
        Also includes the files in |declareIncludes| in the header
 | 
						|
        file and the files in |defineIncludes| in the .cpp.
 | 
						|
        """
 | 
						|
 | 
						|
        # Determine the filenames for which we need headers.
 | 
						|
        interfaceDeps = [d.interface for d in descriptors]
 | 
						|
        ancestors = []
 | 
						|
        for iface in interfaceDeps:
 | 
						|
            while iface.parent:
 | 
						|
                ancestors.append(iface.parent)
 | 
						|
                iface = iface.parent
 | 
						|
        interfaceDeps.extend(ancestors)
 | 
						|
        bindingIncludes = set(self.getDeclarationFilename(d) for d in interfaceDeps)
 | 
						|
 | 
						|
        # Grab all the implementation declaration files we need.
 | 
						|
        implementationIncludes = set(d.headerFile for d in descriptors)
 | 
						|
 | 
						|
        # Now find all the things we'll need as arguments because we
 | 
						|
        # need to wrap or unwrap them.
 | 
						|
        bindingHeaders = set()
 | 
						|
        for d in descriptors:
 | 
						|
            types = getTypes(d)
 | 
						|
            for dictionary in dictionaries:
 | 
						|
                curDict = dictionary
 | 
						|
                while curDict:
 | 
						|
                    types.extend([m.type for m in curDict.members])
 | 
						|
                    curDict = curDict.parent
 | 
						|
 | 
						|
            for t in types:
 | 
						|
                if t.unroll().isUnion():
 | 
						|
                    # UnionConversions.h includes UnionTypes.h
 | 
						|
                    bindingHeaders.add("mozilla/dom/UnionConversions.h")
 | 
						|
                elif t.unroll().isInterface():
 | 
						|
                    if t.unroll().isSpiderMonkeyInterface():
 | 
						|
                        bindingHeaders.add("jsfriendapi.h")
 | 
						|
                        bindingHeaders.add("mozilla/dom/TypedArray.h")
 | 
						|
                    else:
 | 
						|
                        typeDesc = d.getDescriptor(t.unroll().inner.identifier.name)
 | 
						|
                        if typeDesc is not None:
 | 
						|
                            implementationIncludes.add(typeDesc.headerFile)
 | 
						|
                            bindingHeaders.add(self.getDeclarationFilename(typeDesc.interface))
 | 
						|
                elif t.unroll().isDictionary():
 | 
						|
                    bindingHeaders.add(self.getDeclarationFilename(t.unroll().inner))
 | 
						|
 | 
						|
        declareIncludes = set(declareIncludes)
 | 
						|
        for d in dictionaries:
 | 
						|
            if d.parent:
 | 
						|
                declareIncludes.add(self.getDeclarationFilename(d.parent))
 | 
						|
            bindingHeaders.add(self.getDeclarationFilename(d))
 | 
						|
 | 
						|
        # Let the machinery do its thing.
 | 
						|
        def _includeString(includes):
 | 
						|
            return ''.join(['#include "%s"\n' % i for i in includes]) + '\n'
 | 
						|
        CGWrapper.__init__(self, child,
 | 
						|
                           declarePre=_includeString(sorted(declareIncludes)),
 | 
						|
                           definePre=_includeString(sorted(set(defineIncludes) |
 | 
						|
                                                           bindingIncludes |
 | 
						|
                                                           bindingHeaders |
 | 
						|
                                                           implementationIncludes)))
 | 
						|
    @staticmethod
 | 
						|
    def getDeclarationFilename(decl):
 | 
						|
        # Use our local version of the header, not the exported one, so that
 | 
						|
        # test bindings, which don't export, will work correctly.
 | 
						|
        basename = os.path.basename(decl.filename())
 | 
						|
        return basename.replace('.webidl', 'Binding.h')
 | 
						|
 | 
						|
def SortedTuples(l):
 | 
						|
    """
 | 
						|
    Sort a list of tuples based on the first item in the tuple
 | 
						|
    """
 | 
						|
    return sorted(l, key=operator.itemgetter(0))
 | 
						|
 | 
						|
def SortedDictValues(d):
 | 
						|
    """
 | 
						|
    Returns a list of values from the dict sorted by key.
 | 
						|
    """
 | 
						|
    # Create a list of tuples containing key and value, sorted on key.
 | 
						|
    d = SortedTuples(d.items())
 | 
						|
    # We're only interested in the values.
 | 
						|
    return (i[1] for i in d)
 | 
						|
 | 
						|
def UnionTypes(descriptors):
 | 
						|
    """
 | 
						|
    Returns a tuple containing a set of header filenames to include, a set of
 | 
						|
    tuples containing a type declaration and a boolean if the type is a struct
 | 
						|
    for member types of the unions and a CGList containing CGUnionStructs for
 | 
						|
    every union.
 | 
						|
    """
 | 
						|
 | 
						|
    # Now find all the things we'll need as arguments and return values because
 | 
						|
    # we need to wrap or unwrap them.
 | 
						|
    headers = set()
 | 
						|
    declarations = set()
 | 
						|
    unionStructs = dict()
 | 
						|
    for d in descriptors:
 | 
						|
        if d.interface.isExternal():
 | 
						|
            continue
 | 
						|
 | 
						|
        for t in getTypes(d):
 | 
						|
            t = t.unroll()
 | 
						|
            if t.isUnion():
 | 
						|
                name = str(t)
 | 
						|
                if not name in unionStructs:
 | 
						|
                    unionStructs[name] = CGUnionStruct(t, d)
 | 
						|
                    for f in t.flatMemberTypes:
 | 
						|
                        f = f.unroll()
 | 
						|
                        if f.isInterface():
 | 
						|
                            if f.isSpiderMonkeyInterface():
 | 
						|
                                headers.add("jsfriendapi.h")
 | 
						|
                                headers.add("mozilla/dom/TypedArray.h")
 | 
						|
                            else:
 | 
						|
                                typeDesc = d.getDescriptor(f.inner.identifier.name)
 | 
						|
                                if typeDesc is not None:
 | 
						|
                                    declarations.add((typeDesc.nativeType, False))
 | 
						|
                        elif f.isDictionary():
 | 
						|
                            declarations.add((f.inner.identifier.name, True))
 | 
						|
 | 
						|
    return (headers, declarations, CGList(SortedDictValues(unionStructs), "\n"))
 | 
						|
 | 
						|
def UnionConversions(descriptors):
 | 
						|
    """
 | 
						|
    Returns a CGThing to declare all union argument conversion helper structs.
 | 
						|
    """
 | 
						|
    # Now find all the things we'll need as arguments because we
 | 
						|
    # need to unwrap them.
 | 
						|
    unionConversions = dict()
 | 
						|
    for d in descriptors:
 | 
						|
        if d.interface.isExternal():
 | 
						|
            continue
 | 
						|
 | 
						|
        def addUnionTypes(type):
 | 
						|
            if type.isUnion():
 | 
						|
                type = type.unroll()
 | 
						|
                name = str(type)
 | 
						|
                if not name in unionConversions:
 | 
						|
                    unionConversions[name] = CGUnionConversionStruct(type, d)
 | 
						|
 | 
						|
        members = [m for m in d.interface.members]
 | 
						|
        if d.interface.ctor():
 | 
						|
            members.append(d.interface.ctor())
 | 
						|
        signatures = [s for m in members if m.isMethod() for s in m.signatures()]
 | 
						|
        for s in signatures:
 | 
						|
            assert len(s) == 2
 | 
						|
            (_, arguments) = s
 | 
						|
            for a in arguments:
 | 
						|
                addUnionTypes(a.type)
 | 
						|
 | 
						|
        for m in members:
 | 
						|
            if m.isAttr() and not m.readonly:
 | 
						|
                addUnionTypes(m.type)
 | 
						|
 | 
						|
    return CGWrapper(CGList(SortedDictValues(unionConversions), "\n"),
 | 
						|
                     post="\n\n")
 | 
						|
 | 
						|
class Argument():
 | 
						|
    """
 | 
						|
    A class for outputting the type and name of an argument
 | 
						|
    """
 | 
						|
    def __init__(self, argType, name):
 | 
						|
        self.argType = argType
 | 
						|
        self.name = name
 | 
						|
    def __str__(self):
 | 
						|
        return self.argType + ' ' + self.name
 | 
						|
 | 
						|
class CGAbstractMethod(CGThing):
 | 
						|
    """
 | 
						|
    An abstract class for generating code for a method.  Subclasses
 | 
						|
    should override definition_body to create the actual code.
 | 
						|
 | 
						|
    descriptor is the descriptor for the interface the method is associated with
 | 
						|
 | 
						|
    name is the name of the method as a string
 | 
						|
 | 
						|
    returnType is the IDLType of the return value
 | 
						|
 | 
						|
    args is a list of Argument objects
 | 
						|
 | 
						|
    inline should be True to generate an inline method, whose body is
 | 
						|
    part of the declaration.
 | 
						|
 | 
						|
    alwaysInline should be True to generate an inline method annotated with
 | 
						|
    MOZ_ALWAYS_INLINE.
 | 
						|
 | 
						|
    static should be True to generate a static method, which only has
 | 
						|
    a definition.
 | 
						|
 | 
						|
    If templateArgs is not None it should be a list of strings containing
 | 
						|
    template arguments, and the function will be templatized using those
 | 
						|
    arguments.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, static=False, templateArgs=None):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.descriptor = descriptor
 | 
						|
        self.name = name
 | 
						|
        self.returnType = returnType
 | 
						|
        self.args = args
 | 
						|
        self.inline = inline
 | 
						|
        self.alwaysInline = alwaysInline
 | 
						|
        self.static = static
 | 
						|
        self.templateArgs = templateArgs
 | 
						|
    def _argstring(self):
 | 
						|
        return ', '.join([str(a) for a in self.args])
 | 
						|
    def _template(self):
 | 
						|
        if self.templateArgs is None:
 | 
						|
            return ''
 | 
						|
        return 'template <%s>\n' % ', '.join(self.templateArgs)
 | 
						|
    def _decorators(self):
 | 
						|
        decorators = []
 | 
						|
        if self.alwaysInline:
 | 
						|
            decorators.append('MOZ_ALWAYS_INLINE')
 | 
						|
        elif self.inline:
 | 
						|
            decorators.append('inline')
 | 
						|
        if self.static:
 | 
						|
            decorators.append('static')
 | 
						|
        decorators.append(self.returnType)
 | 
						|
        maybeNewline = " " if self.inline else "\n"
 | 
						|
        return ' '.join(decorators) + maybeNewline
 | 
						|
    def declare(self):
 | 
						|
        if self.inline:
 | 
						|
            return self._define()
 | 
						|
        return "%s%s%s(%s);\n" % (self._template(), self._decorators(), self.name, self._argstring())
 | 
						|
    def _define(self):
 | 
						|
        return self.definition_prologue() + "\n" + self.definition_body() + self.definition_epilogue()
 | 
						|
    def define(self):
 | 
						|
        return "" if self.inline else self._define()
 | 
						|
    def definition_prologue(self):
 | 
						|
        return "%s%s%s(%s)\n{" % (self._template(), self._decorators(),
 | 
						|
                                  self.name, self._argstring())
 | 
						|
    def definition_epilogue(self):
 | 
						|
        return "\n}\n"
 | 
						|
    def definition_body(self):
 | 
						|
        assert(False) # Override me!
 | 
						|
 | 
						|
class CGAbstractStaticMethod(CGAbstractMethod):
 | 
						|
    """
 | 
						|
    Abstract base class for codegen of implementation-only (no
 | 
						|
    declaration) static methods.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name, returnType, args):
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
 | 
						|
                                  inline=False, static=True)
 | 
						|
    def declare(self):
 | 
						|
        # We only have implementation
 | 
						|
        return ""
 | 
						|
 | 
						|
class CGAbstractClassHook(CGAbstractStaticMethod):
 | 
						|
    """
 | 
						|
    Meant for implementing JSClass hooks, like Finalize or Trace. Does very raw
 | 
						|
    'this' unwrapping as it assumes that the unwrapped type is always known.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name, returnType, args):
 | 
						|
        CGAbstractStaticMethod.__init__(self, descriptor, name, returnType,
 | 
						|
                                        args)
 | 
						|
 | 
						|
    def definition_body_prologue(self):
 | 
						|
        return """
 | 
						|
  %s* self = UnwrapDOMObject<%s>(obj, eRegularDOMObject);
 | 
						|
""" % (self.descriptor.nativeType, self.descriptor.nativeType)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        return self.definition_body_prologue() + self.generate_code()
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        # Override me
 | 
						|
        assert(False)
 | 
						|
 | 
						|
class CGAddPropertyHook(CGAbstractClassHook):
 | 
						|
    """
 | 
						|
    A hook for addProperty, used to preserve our wrapper from GC.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
 | 
						|
                Argument('JSHandleId', 'id'), Argument('JSMutableHandleValue', 'vp')]
 | 
						|
        CGAbstractClassHook.__init__(self, descriptor, ADDPROPERTY_HOOK_NAME,
 | 
						|
                                     'JSBool', args)
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=774279
 | 
						|
        # Using a real trace hook might enable us to deal with non-nsISupports
 | 
						|
        # wrappercached things here.
 | 
						|
        assert self.descriptor.nativeIsISupports
 | 
						|
        return """  nsContentUtils::PreserveWrapper(reinterpret_cast<nsISupports*>(self), self);
 | 
						|
  return true;"""
 | 
						|
 | 
						|
def finalizeHook(descriptor, hookName, context):
 | 
						|
    if descriptor.customFinalize:
 | 
						|
        return """if (self) {
 | 
						|
  self->%s(%s);
 | 
						|
}""" % (hookName, context)
 | 
						|
    clearWrapper = "ClearWrapper(self, self);\n" if descriptor.wrapperCache else ""
 | 
						|
    if descriptor.workers:
 | 
						|
        release = "self->Release();"
 | 
						|
    else:
 | 
						|
        assert descriptor.nativeIsISupports
 | 
						|
        release = """XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
 | 
						|
if (rt) {
 | 
						|
  rt->DeferredRelease(reinterpret_cast<nsISupports*>(self));
 | 
						|
} else {
 | 
						|
  NS_RELEASE(self);
 | 
						|
}"""
 | 
						|
    return clearWrapper + release
 | 
						|
 | 
						|
class CGClassFinalizeHook(CGAbstractClassHook):
 | 
						|
    """
 | 
						|
    A hook for finalize, used to release our native object.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'obj')]
 | 
						|
        CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME,
 | 
						|
                                     'void', args)
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        return CGIndenter(CGGeneric(finalizeHook(self.descriptor, self.name, self.args[0].name))).define()
 | 
						|
 | 
						|
class CGClassTraceHook(CGAbstractClassHook):
 | 
						|
    """
 | 
						|
    A hook to trace through our native object; used for GC and CC
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSTracer*', 'trc'), Argument('JSObject*', 'obj')]
 | 
						|
        CGAbstractClassHook.__init__(self, descriptor, TRACE_HOOK_NAME, 'void',
 | 
						|
                                     args)
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        return """  if (self) {
 | 
						|
    self->%s(%s);
 | 
						|
  }""" % (self.name, self.args[0].name)
 | 
						|
 | 
						|
class CGClassConstructHook(CGAbstractStaticMethod):
 | 
						|
    """
 | 
						|
    JS-visible constructor for our objects
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')]
 | 
						|
        CGAbstractStaticMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME,
 | 
						|
                                        'JSBool', args)
 | 
						|
        self._ctor = self.descriptor.interface.ctor()
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        if not self._ctor:
 | 
						|
            return ""
 | 
						|
        return CGAbstractStaticMethod.define(self)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        return self.generate_code()
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        preamble = """
 | 
						|
  JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
 | 
						|
"""
 | 
						|
        if self.descriptor.workers:
 | 
						|
            preArgs = ["cx", "obj"]
 | 
						|
        else:
 | 
						|
            preamble += """
 | 
						|
  nsISupports* global;
 | 
						|
  xpc_qsSelfRef globalRef;
 | 
						|
  {
 | 
						|
    nsresult rv;
 | 
						|
    JS::Value val = OBJECT_TO_JSVAL(obj);
 | 
						|
    rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr, &val);
 | 
						|
    if (NS_FAILED(rv)) {
 | 
						|
      return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
 | 
						|
    }
 | 
						|
  }
 | 
						|
"""
 | 
						|
            preArgs = ["global"]
 | 
						|
 | 
						|
        name = self._ctor.identifier.name
 | 
						|
        nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
 | 
						|
        callGenerator = CGMethodCall(preArgs, nativeName, True,
 | 
						|
                                     self.descriptor, self._ctor)
 | 
						|
        return preamble + callGenerator.define();
 | 
						|
 | 
						|
class CGClassHasInstanceHook(CGAbstractStaticMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
 | 
						|
                Argument('JSMutableHandleValue', 'vp'), Argument('JSBool*', 'bp')]
 | 
						|
        CGAbstractStaticMethod.__init__(self, descriptor, HASINSTANCE_HOOK_NAME,
 | 
						|
                                        'JSBool', args)
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        if not self.descriptor.hasInstanceInterface:
 | 
						|
            return ""
 | 
						|
        return CGAbstractStaticMethod.define(self)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        return self.generate_code()
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        return """  if (!vp.isObject()) {
 | 
						|
    *bp = false;
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  jsval protov;
 | 
						|
  if (!JS_GetProperty(cx, obj, "prototype", &protov))
 | 
						|
    return false;
 | 
						|
  if (!protov.isObject()) {
 | 
						|
    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE,
 | 
						|
                         "%s");
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  JSObject *objProto = &protov.toObject();
 | 
						|
 | 
						|
  JSObject* instance = &vp.toObject();
 | 
						|
  JSObject* proto;
 | 
						|
  if (!JS_GetPrototype(cx, instance, &proto))
 | 
						|
    return false;
 | 
						|
  while (proto) {
 | 
						|
    if (proto == objProto) {
 | 
						|
      *bp = true;
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    if (!JS_GetPrototype(cx, proto, &proto))
 | 
						|
      return false;
 | 
						|
  }
 | 
						|
 | 
						|
  nsISupports* native =
 | 
						|
    nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, instance);
 | 
						|
  nsCOMPtr<%s> qiResult = do_QueryInterface(native);
 | 
						|
  *bp = !!qiResult;
 | 
						|
  return true;
 | 
						|
""" % (self.descriptor.name, self.descriptor.hasInstanceInterface)
 | 
						|
 | 
						|
def isChromeOnly(m):
 | 
						|
    return m.getExtendedAttribute("ChromeOnly")
 | 
						|
 | 
						|
class PropertyDefiner:
 | 
						|
    """
 | 
						|
    A common superclass for defining things on prototype objects.
 | 
						|
 | 
						|
    Subclasses should implement generateArray to generate the actual arrays of
 | 
						|
    things we're defining.  They should also set self.chrome to the list of
 | 
						|
    things exposed to chrome and self.regular to the list of things exposed to
 | 
						|
    web pages.  self.chrome must be a superset of self.regular but also include
 | 
						|
    all the ChromeOnly stuff.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name):
 | 
						|
        self.descriptor = descriptor
 | 
						|
        self.name = name
 | 
						|
        # self.prefCacheData will store an array of (prefname, bool*)
 | 
						|
        # pairs for our bool var caches.  generateArray will fill it
 | 
						|
        # in as needed.
 | 
						|
        self.prefCacheData = []
 | 
						|
    def hasChromeOnly(self):
 | 
						|
        return len(self.chrome) > len(self.regular)
 | 
						|
    def hasNonChromeOnly(self):
 | 
						|
        return len(self.regular) > 0
 | 
						|
    def variableName(self, chrome):
 | 
						|
        if chrome and self.hasChromeOnly():
 | 
						|
            return "sChrome" + self.name
 | 
						|
        if self.hasNonChromeOnly():
 | 
						|
            return "s" + self.name
 | 
						|
        return "NULL"
 | 
						|
    def usedForXrays(self, chrome):
 | 
						|
        # We only need Xrays for methods, attributes and constants.  And we only
 | 
						|
        # need them for the non-chrome ones if we have no chromeonly things.
 | 
						|
        # Otherwise (we have chromeonly attributes) we need Xrays for the chrome
 | 
						|
        # methods/attributes/constants.  Finally, in workers there are no Xrays.
 | 
						|
        return ((self.name is "Methods" or self.name is "Attributes" or
 | 
						|
                 self.name is "Constants") and
 | 
						|
                chrome == self.hasChromeOnly() and
 | 
						|
                not self.descriptor.workers)
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        # We only need to generate id arrays for things that will end
 | 
						|
        # up used via ResolveProperty or EnumerateProperties.
 | 
						|
        str = self.generateArray(self.regular, self.variableName(False),
 | 
						|
                                 self.usedForXrays(False))
 | 
						|
        if self.hasChromeOnly():
 | 
						|
            str += self.generateArray(self.chrome, self.variableName(True),
 | 
						|
                                      self.usedForXrays(True))
 | 
						|
        return str
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def getControllingPref(interfaceMember):
 | 
						|
        prefName = interfaceMember.getExtendedAttribute("Pref")
 | 
						|
        if prefName is None:
 | 
						|
            return None
 | 
						|
        # It's a list of strings
 | 
						|
        assert(len(prefName) is 1)
 | 
						|
        assert(prefName[0] is not None)
 | 
						|
        return prefName[0]
 | 
						|
 | 
						|
    def generatePrefableArray(self, array, name, specTemplate, specTerminator,
 | 
						|
                              specType, getPref, getDataTuple, doIdArrays):
 | 
						|
        """
 | 
						|
        This method generates our various arrays.
 | 
						|
 | 
						|
        array is an array of interface members as passed to generateArray
 | 
						|
 | 
						|
        name is the name as passed to generateArray
 | 
						|
 | 
						|
        specTemplate is a template for each entry of the spec array
 | 
						|
 | 
						|
        specTerminator is a terminator for the spec array (inserted every time
 | 
						|
          our controlling pref changes and at the end of the array)
 | 
						|
 | 
						|
        specType is the actual typename of our spec
 | 
						|
 | 
						|
        getPref is a callback function that takes an array entry and returns
 | 
						|
          the corresponding pref value.
 | 
						|
 | 
						|
        getDataTuple is a callback function that takes an array entry and
 | 
						|
          returns a tuple suitable for substitution into specTemplate.
 | 
						|
        """
 | 
						|
 | 
						|
        # We want to generate a single list of specs, but with specTerminator
 | 
						|
        # inserted at every point where the pref name controlling the member
 | 
						|
        # changes.  That will make sure the order of the properties as exposed
 | 
						|
        # on the interface and interface prototype objects does not change when
 | 
						|
        # pref control is added to members while still allowing us to define all
 | 
						|
        # the members in the smallest number of JSAPI calls.
 | 
						|
        assert(len(array) is not 0)
 | 
						|
        lastPref = getPref(array[0]) # So we won't put a specTerminator
 | 
						|
                                     # at the very front of the list.
 | 
						|
        specs = []
 | 
						|
        prefableSpecs = []
 | 
						|
        if doIdArrays:
 | 
						|
            prefableIds = []
 | 
						|
 | 
						|
        prefableTemplate = '  { true, &%s[%d] }'
 | 
						|
        prefCacheTemplate = '&%s[%d].enabled'
 | 
						|
        def switchToPref(props, pref):
 | 
						|
            # Remember the info about where our pref-controlled
 | 
						|
            # booleans live.
 | 
						|
            if pref is not None:
 | 
						|
                props.prefCacheData.append(
 | 
						|
                    (pref, prefCacheTemplate % (name, len(prefableSpecs)))
 | 
						|
                    )
 | 
						|
            # Set up pointers to the new sets of specs and ids
 | 
						|
            # inside prefableSpecs and prefableIds
 | 
						|
            prefableSpecs.append(prefableTemplate %
 | 
						|
                                 (name + "_specs", len(specs)))
 | 
						|
 | 
						|
        switchToPref(self, lastPref)
 | 
						|
 | 
						|
        for member in array:
 | 
						|
            curPref = getPref(member)
 | 
						|
            if lastPref != curPref:
 | 
						|
                # Terminate previous list
 | 
						|
                specs.append(specTerminator)
 | 
						|
                # And switch to our new pref
 | 
						|
                switchToPref(self, curPref)
 | 
						|
                lastPref = curPref
 | 
						|
            # And the actual spec
 | 
						|
            specs.append(specTemplate % getDataTuple(member))
 | 
						|
        specs.append(specTerminator)
 | 
						|
        prefableSpecs.append("  { false, NULL }");
 | 
						|
 | 
						|
        arrays = (("static %s %s_specs[] = {\n" +
 | 
						|
                   ',\n'.join(specs) + "\n" +
 | 
						|
                   "};\n\n" +
 | 
						|
                   "static Prefable<%s> %s[] = {\n" +
 | 
						|
                   ',\n'.join(prefableSpecs) + "\n" +
 | 
						|
                   "};\n\n") % (specType, name, specType, name))
 | 
						|
        if doIdArrays:
 | 
						|
            arrays += ("static jsid %s_ids[%i] = { JSID_VOID };\n\n" %
 | 
						|
                       (name, len(specs)))
 | 
						|
        return arrays
 | 
						|
 | 
						|
 | 
						|
# The length of a method is the maximum of the lengths of the
 | 
						|
# argument lists of all its overloads.
 | 
						|
def methodLength(method):
 | 
						|
    signatures = method.signatures()
 | 
						|
    return max([len(arguments) for (retType, arguments) in signatures])
 | 
						|
 | 
						|
class MethodDefiner(PropertyDefiner):
 | 
						|
    """
 | 
						|
    A class for defining methods on a prototype object.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name, static):
 | 
						|
        PropertyDefiner.__init__(self, descriptor, name)
 | 
						|
 | 
						|
        # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
 | 
						|
        #       We should be able to check for special operations without an
 | 
						|
        #       identifier. For now we check if the name starts with __
 | 
						|
        methods = [m for m in descriptor.interface.members if
 | 
						|
                   m.isMethod() and m.isStatic() == static and
 | 
						|
                   not m.isIdentifierLess()]
 | 
						|
        self.chrome = [{"name": m.identifier.name,
 | 
						|
                        "length": methodLength(m),
 | 
						|
                        "flags": "JSPROP_ENUMERATE",
 | 
						|
                        "pref": PropertyDefiner.getControllingPref(m) }
 | 
						|
                       for m in methods]
 | 
						|
        self.regular = [{"name": m.identifier.name,
 | 
						|
                         "length": methodLength(m),
 | 
						|
                         "flags": "JSPROP_ENUMERATE",
 | 
						|
                         "pref": PropertyDefiner.getControllingPref(m) }
 | 
						|
                        for m in methods if not isChromeOnly(m)]
 | 
						|
 | 
						|
        # FIXME Check for an existing iterator on the interface first.
 | 
						|
        if any(m.isGetter() and m.isIndexed() for m in methods):
 | 
						|
            self.chrome.append({"name": 'iterator',
 | 
						|
                                "methodInfo": False,
 | 
						|
                                "nativeName": "JS_ArrayIterator",
 | 
						|
                                "length": 0,
 | 
						|
                                "flags": "JSPROP_ENUMERATE",
 | 
						|
                                "pref": None })
 | 
						|
            self.regular.append({"name": 'iterator',
 | 
						|
                                 "methodInfo": False,
 | 
						|
                                 "nativeName": "JS_ArrayIterator",
 | 
						|
                                 "length": 0,
 | 
						|
                                 "flags": "JSPROP_ENUMERATE",
 | 
						|
                                 "pref": None })
 | 
						|
 | 
						|
        if not descriptor.interface.parent and not static and not descriptor.workers:
 | 
						|
            self.chrome.append({"name": 'QueryInterface',
 | 
						|
                                "methodInfo": False,
 | 
						|
                                "length": 1,
 | 
						|
                                "flags": "0",
 | 
						|
                                "pref": None })
 | 
						|
 | 
						|
        if static:
 | 
						|
            if not descriptor.interface.hasInterfaceObject():
 | 
						|
                # static methods go on the interface object
 | 
						|
                assert not self.hasChromeOnly() and not self.hasNonChromeOnly()
 | 
						|
        else:
 | 
						|
            if not descriptor.interface.hasInterfacePrototypeObject():
 | 
						|
                # non-static methods go on the interface prototype object
 | 
						|
                assert not self.hasChromeOnly() and not self.hasNonChromeOnly()
 | 
						|
 | 
						|
    def generateArray(self, array, name, doIdArrays):
 | 
						|
        if len(array) == 0:
 | 
						|
            return ""
 | 
						|
 | 
						|
        def pref(m):
 | 
						|
            return m["pref"]
 | 
						|
 | 
						|
        def specData(m):
 | 
						|
            if m.get("methodInfo", True):
 | 
						|
                jitinfo = ("&%s_methodinfo" % m["name"])
 | 
						|
                accessor = "genericMethod"
 | 
						|
            else:
 | 
						|
                jitinfo = "nullptr"
 | 
						|
                accessor = m.get("nativeName", m["name"])
 | 
						|
            return (m["name"], accessor, jitinfo, m["length"], m["flags"])
 | 
						|
 | 
						|
        return self.generatePrefableArray(
 | 
						|
            array, name,
 | 
						|
            '  JS_FNINFO("%s", %s, %s, %s, %s)',
 | 
						|
            '  JS_FS_END',
 | 
						|
            'JSFunctionSpec',
 | 
						|
            pref, specData, doIdArrays)
 | 
						|
 | 
						|
class AttrDefiner(PropertyDefiner):
 | 
						|
    def __init__(self, descriptor, name):
 | 
						|
        PropertyDefiner.__init__(self, descriptor, name)
 | 
						|
        self.name = name
 | 
						|
        self.chrome = [m for m in descriptor.interface.members if m.isAttr()]
 | 
						|
        self.regular = [m for m in self.chrome if not isChromeOnly(m)]
 | 
						|
 | 
						|
    def generateArray(self, array, name, doIdArrays):
 | 
						|
        if len(array) == 0:
 | 
						|
            return ""
 | 
						|
 | 
						|
        def flags(attr):
 | 
						|
            return "JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS"
 | 
						|
 | 
						|
        def getter(attr):
 | 
						|
            native = ("genericLenientGetter" if attr.hasLenientThis()
 | 
						|
                      else "genericGetter")
 | 
						|
            return ("{(JSPropertyOp)%(native)s, &%(name)s_getterinfo}"
 | 
						|
                    % {"name" : attr.identifier.name,
 | 
						|
                       "native" : native})
 | 
						|
 | 
						|
        def setter(attr):
 | 
						|
            if attr.readonly:
 | 
						|
                return "JSOP_NULLWRAPPER"
 | 
						|
            native = ("genericLenientSetter" if attr.hasLenientThis()
 | 
						|
                      else "genericSetter")
 | 
						|
            return ("{(JSStrictPropertyOp)%(native)s, &%(name)s_setterinfo}"
 | 
						|
                    % {"name" : attr.identifier.name,
 | 
						|
                       "native" : native})
 | 
						|
 | 
						|
        def specData(attr):
 | 
						|
            return (attr.identifier.name, flags(attr), getter(attr),
 | 
						|
                    setter(attr))
 | 
						|
 | 
						|
        return self.generatePrefableArray(
 | 
						|
            array, name,
 | 
						|
            '  { "%s", 0, %s, %s, %s}',
 | 
						|
            '  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }',
 | 
						|
            'JSPropertySpec',
 | 
						|
            PropertyDefiner.getControllingPref, specData, doIdArrays)
 | 
						|
 | 
						|
class ConstDefiner(PropertyDefiner):
 | 
						|
    """
 | 
						|
    A class for definining constants on the interface object
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name):
 | 
						|
        PropertyDefiner.__init__(self, descriptor, name)
 | 
						|
        self.name = name
 | 
						|
        self.chrome = [m for m in descriptor.interface.members if m.isConst()]
 | 
						|
        self.regular = [m for m in self.chrome if not isChromeOnly(m)]
 | 
						|
 | 
						|
    def generateArray(self, array, name, doIdArrays):
 | 
						|
        if len(array) == 0:
 | 
						|
            return ""
 | 
						|
 | 
						|
        def specData(const):
 | 
						|
            return (const.identifier.name,
 | 
						|
                    convertConstIDLValueToJSVal(const.value))
 | 
						|
 | 
						|
        return self.generatePrefableArray(
 | 
						|
            array, name,
 | 
						|
            '  { "%s", %s }',
 | 
						|
            '  { 0, JSVAL_VOID }',
 | 
						|
            'ConstantSpec',
 | 
						|
            PropertyDefiner.getControllingPref, specData, doIdArrays)
 | 
						|
 | 
						|
class PropertyArrays():
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        self.staticMethods = MethodDefiner(descriptor, "StaticMethods", True)
 | 
						|
        self.methods = MethodDefiner(descriptor, "Methods", False)
 | 
						|
        self.attrs = AttrDefiner(descriptor, "Attributes")
 | 
						|
        self.consts = ConstDefiner(descriptor, "Constants")
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def arrayNames():
 | 
						|
        return [ "staticMethods", "methods", "attrs", "consts" ]
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def xrayRelevantArrayNames():
 | 
						|
        return [ "methods", "attrs", "consts" ]
 | 
						|
 | 
						|
    def hasChromeOnly(self):
 | 
						|
        return reduce(lambda b, a: b or getattr(self, a).hasChromeOnly(),
 | 
						|
                      self.arrayNames(), False)
 | 
						|
    def variableNames(self, chrome):
 | 
						|
        names = {}
 | 
						|
        for array in self.arrayNames():
 | 
						|
            names[array] = getattr(self, array).variableName(chrome)
 | 
						|
        return names
 | 
						|
    def __str__(self):
 | 
						|
        define = ""
 | 
						|
        for array in self.arrayNames():
 | 
						|
            define += str(getattr(self, array))
 | 
						|
        return define
 | 
						|
 | 
						|
class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
 | 
						|
    """
 | 
						|
    Generate the CreateInterfaceObjects method for an interface descriptor.
 | 
						|
 | 
						|
    properties should be a PropertyArrays instance.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, properties):
 | 
						|
        args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal'),
 | 
						|
                Argument('JSObject*', 'aReceiver')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'JSObject*', args)
 | 
						|
        self.properties = properties
 | 
						|
    def definition_body(self):
 | 
						|
        protoChain = self.descriptor.prototypeChain
 | 
						|
        if len(protoChain) == 1:
 | 
						|
            getParentProto = "JS_GetObjectPrototype(aCx, aGlobal)"
 | 
						|
        else:
 | 
						|
            parentProtoName = self.descriptor.prototypeChain[-2]
 | 
						|
            getParentProto = ("%s::GetProtoObject(aCx, aGlobal, aReceiver)" %
 | 
						|
                              toBindingNamespace(parentProtoName))
 | 
						|
 | 
						|
        needInterfaceObject = self.descriptor.interface.hasInterfaceObject()
 | 
						|
        needInterfacePrototypeObject = self.descriptor.interface.hasInterfacePrototypeObject()
 | 
						|
 | 
						|
        # if we don't need to create anything, why are we generating this?
 | 
						|
        assert needInterfaceObject or needInterfacePrototypeObject
 | 
						|
 | 
						|
        idsToInit = []
 | 
						|
        # There is no need to init any IDs in workers, because worker bindings
 | 
						|
        # don't have Xrays.
 | 
						|
        if not self.descriptor.workers:
 | 
						|
            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.
 | 
						|
                if props.hasChromeOnly():
 | 
						|
                    idsToInit.append(props.variableName(True))
 | 
						|
                elif props.hasNonChromeOnly():
 | 
						|
                    idsToInit.append(props.variableName(False))
 | 
						|
        if len(idsToInit) > 0:
 | 
						|
            initIds = CGList(
 | 
						|
                [CGGeneric("!InitIds(aCx, %s, %s_ids)" % (varname, varname)) for
 | 
						|
                 varname in idsToInit], ' ||\n')
 | 
						|
            if len(idsToInit) > 1:
 | 
						|
                initIds = CGWrapper(initIds, pre="(", post=")", reindent=True)
 | 
						|
            initIds = CGList(
 | 
						|
                [CGGeneric("%s_ids[0] == JSID_VOID &&" % idsToInit[0]), initIds],
 | 
						|
                "\n")
 | 
						|
            initIds = CGWrapper(initIds, pre="if (", post=") {", reindent=True)
 | 
						|
            initIds = CGList(
 | 
						|
                [initIds,
 | 
						|
                 CGGeneric(("  %s_ids[0] = JSID_VOID;\n"
 | 
						|
                            "  return NULL;") % idsToInit[0]),
 | 
						|
                 CGGeneric("}")],
 | 
						|
                "\n")
 | 
						|
        else:
 | 
						|
            initIds = None
 | 
						|
 | 
						|
        prefCacheData = []
 | 
						|
        for var in self.properties.arrayNames():
 | 
						|
            props = getattr(self.properties, var)
 | 
						|
            prefCacheData.extend(props.prefCacheData)
 | 
						|
        if len(prefCacheData) is not 0:
 | 
						|
            prefCacheData = [
 | 
						|
                CGGeneric('Preferences::AddBoolVarCache(%s, "%s");' % (ptr, pref)) for
 | 
						|
                (pref, ptr) in prefCacheData]
 | 
						|
            prefCache = CGWrapper(CGIndenter(CGList(prefCacheData, "\n")),
 | 
						|
                                  pre=("static bool sPrefCachesInited = false;\n"
 | 
						|
                                       "if (!sPrefCachesInited) {\n"
 | 
						|
                                       "  sPrefCachesInited = true;\n"),
 | 
						|
                                  post="\n}")
 | 
						|
        else:
 | 
						|
            prefCache = None
 | 
						|
            
 | 
						|
        getParentProto = ("JSObject* parentProto = %s;\n" +
 | 
						|
                          "if (!parentProto) {\n" +
 | 
						|
                          "  return NULL;\n" +
 | 
						|
                          "}\n") % getParentProto
 | 
						|
 | 
						|
        needInterfaceObjectClass = (needInterfaceObject and
 | 
						|
                                    self.descriptor.hasInstanceInterface)
 | 
						|
        needConstructor = (needInterfaceObject and
 | 
						|
                           not self.descriptor.hasInstanceInterface)
 | 
						|
        if self.descriptor.interface.ctor():
 | 
						|
            constructHook = CONSTRUCT_HOOK_NAME
 | 
						|
            constructArgs = methodLength(self.descriptor.interface.ctor())
 | 
						|
        else:
 | 
						|
            constructHook = "ThrowingConstructor"
 | 
						|
            constructArgs = 0
 | 
						|
 | 
						|
        if self.descriptor.concrete:
 | 
						|
            if self.descriptor.proxy:
 | 
						|
                domClass = "&Class"
 | 
						|
            else:
 | 
						|
                domClass = "&Class.mClass"
 | 
						|
        else:
 | 
						|
            domClass = "nullptr"
 | 
						|
 | 
						|
        call = """return dom::CreateInterfaceObjects(aCx, aGlobal, aReceiver, parentProto,
 | 
						|
                                   %s, %s, %s, %d,
 | 
						|
                                   %s,
 | 
						|
                                   %%(methods)s, %%(attrs)s,
 | 
						|
                                   %%(consts)s, %%(staticMethods)s,
 | 
						|
                                   %s);""" % (
 | 
						|
            "&PrototypeClass" if needInterfacePrototypeObject else "NULL",
 | 
						|
            "&InterfaceObjectClass" if needInterfaceObjectClass else "NULL",
 | 
						|
            constructHook if needConstructor else "NULL",
 | 
						|
            constructArgs,
 | 
						|
            domClass,
 | 
						|
            '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "NULL")
 | 
						|
        if self.properties.hasChromeOnly():
 | 
						|
            if self.descriptor.workers:
 | 
						|
                accessCheck = "mozilla::dom::workers::GetWorkerPrivateFromContext(aCx)->IsChromeWorker()"
 | 
						|
            else:
 | 
						|
                accessCheck = "xpc::AccessCheck::isChrome(js::GetObjectCompartment(aGlobal))"
 | 
						|
            chrome = CGIfWrapper(CGGeneric(call % self.properties.variableNames(True)),
 | 
						|
                                 accessCheck)
 | 
						|
            chrome = CGWrapper(chrome, pre="\n\n")
 | 
						|
        else:
 | 
						|
            chrome = None
 | 
						|
 | 
						|
        functionBody = CGList(
 | 
						|
            [CGGeneric(getParentProto), initIds, prefCache, chrome,
 | 
						|
             CGGeneric(call % self.properties.variableNames(False))],
 | 
						|
            "\n\n")
 | 
						|
        return CGIndenter(functionBody).define()
 | 
						|
 | 
						|
class CGGetPerInterfaceObject(CGAbstractMethod):
 | 
						|
    """
 | 
						|
    A method for getting a per-interface object (a prototype object or interface
 | 
						|
    constructor object).
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name, idPrefix=""):
 | 
						|
        args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal'),
 | 
						|
                Argument('JSObject*', 'aReceiver')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, name,
 | 
						|
                                  'JSObject*', args, inline=True)
 | 
						|
        self.id = idPrefix + "id::" + self.descriptor.name
 | 
						|
    def definition_body(self):
 | 
						|
        return """
 | 
						|
 | 
						|
  /* aGlobal and aReceiver are usually the same, but they can be different
 | 
						|
     too. For example a sandbox often has an xray wrapper for a window as the
 | 
						|
     prototype of the sandbox's global. In that case aReceiver is the xray
 | 
						|
     wrapper and aGlobal is the sandbox's global.
 | 
						|
   */
 | 
						|
 | 
						|
  /* Make sure our global is sane.  Hopefully we can remove this sometime */
 | 
						|
  if (!(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL)) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  /* Check to see whether the interface objects are already installed */
 | 
						|
  JSObject** protoOrIfaceArray = GetProtoOrIfaceArray(aGlobal);
 | 
						|
  JSObject* cachedObject = protoOrIfaceArray[%s];
 | 
						|
  if (!cachedObject) {
 | 
						|
    protoOrIfaceArray[%s] = cachedObject = CreateInterfaceObjects(aCx, aGlobal, aReceiver);
 | 
						|
  }
 | 
						|
 | 
						|
  /* cachedObject might _still_ be null, but that's OK */
 | 
						|
  return cachedObject;""" % (self.id, self.id)
 | 
						|
 | 
						|
class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
 | 
						|
    """
 | 
						|
    A method for getting the interface prototype object.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
 | 
						|
                                         "prototypes::")
 | 
						|
    def definition_body(self):
 | 
						|
        return """
 | 
						|
  /* Get the interface prototype object for this class.  This will create the
 | 
						|
     object as needed. */""" + CGGetPerInterfaceObject.definition_body(self)
 | 
						|
 | 
						|
class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
 | 
						|
    """
 | 
						|
    A method for getting the interface constructor object.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject",
 | 
						|
                                         "constructors::")
 | 
						|
    def definition_body(self):
 | 
						|
        return """
 | 
						|
  /* Get the interface object for this class.  This will create the object as
 | 
						|
     needed. */""" + CGGetPerInterfaceObject.definition_body(self)
 | 
						|
 | 
						|
def CheckPref(descriptor, globalName, varName, retval, wrapperCache = None):
 | 
						|
    """
 | 
						|
    Check whether bindings should be enabled for this descriptor.  If not, set
 | 
						|
    varName to false and return retval.
 | 
						|
    """
 | 
						|
    if not descriptor.prefable:
 | 
						|
        return ""
 | 
						|
 | 
						|
    if wrapperCache:
 | 
						|
       wrapperCache = "      %s->ClearIsDOMBinding();\n" % (wrapperCache)
 | 
						|
    else:
 | 
						|
        wrapperCache = ""
 | 
						|
 | 
						|
    failureCode = ("      %s = false;\n" +
 | 
						|
                   "      return %s;") % (varName, retval)
 | 
						|
    return """
 | 
						|
  {
 | 
						|
    XPCWrappedNativeScope* scope =
 | 
						|
      XPCWrappedNativeScope::FindInJSObjectScope(aCx, %s);
 | 
						|
    if (!scope) {
 | 
						|
%s
 | 
						|
    }
 | 
						|
 | 
						|
    if (!scope->ExperimentalBindingsEnabled()) {
 | 
						|
%s%s
 | 
						|
    }
 | 
						|
  }
 | 
						|
""" % (globalName, failureCode, wrapperCache, failureCode)
 | 
						|
 | 
						|
class CGDefineDOMInterfaceMethod(CGAbstractMethod):
 | 
						|
    """
 | 
						|
    A method for resolve hooks to try to lazily define the interface object for
 | 
						|
    a given interface.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aReceiver'),
 | 
						|
                Argument('bool*', 'aEnabled')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'bool', args)
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        if self.descriptor.workers:
 | 
						|
            return ''
 | 
						|
        return CGAbstractMethod.declare(self)
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        if self.descriptor.workers:
 | 
						|
            return ''
 | 
						|
        return CGAbstractMethod.define(self)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        if self.descriptor.interface.hasInterfacePrototypeObject():
 | 
						|
            # We depend on GetProtoObject defining an interface constructor
 | 
						|
            # object as needed.
 | 
						|
            getter = "GetProtoObject"
 | 
						|
        else:
 | 
						|
            getter = "GetConstructorObject"
 | 
						|
 | 
						|
        return ("  JSObject* global = JS_GetGlobalForObject(aCx, aReceiver);\n" +
 | 
						|
                CheckPref(self.descriptor, "global", "*aEnabled", "false") + 
 | 
						|
                """
 | 
						|
  *aEnabled = true;
 | 
						|
  return !!%s(aCx, global, aReceiver);""" % (getter))
 | 
						|
 | 
						|
class CGPrefEnabled(CGAbstractMethod):
 | 
						|
    """
 | 
						|
    A method for testing whether the preference controlling this
 | 
						|
    interface is enabled.  When it's not, the interface should not be
 | 
						|
    visible on the global.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, 'PrefEnabled', 'bool', [])
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        return CGAbstractMethod.declare(self)
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return CGAbstractMethod.define(self)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        return "  return %s::PrefEnabled();" % self.descriptor.nativeType
 | 
						|
 | 
						|
class CGIsMethod(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSObject*', 'obj')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, 'Is', 'bool', args)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        # Non-proxy implementation would check
 | 
						|
        #   js::GetObjectJSClass(obj) == &Class.mBase
 | 
						|
        return """  return IsProxy(obj);"""
 | 
						|
 | 
						|
def CreateBindingJSObject(descriptor, parent):
 | 
						|
    if descriptor.proxy:
 | 
						|
        create = """  JSObject *obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
 | 
						|
                                 JS::PrivateValue(aObject), proto, %s);
 | 
						|
  if (!obj) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
"""
 | 
						|
    else:
 | 
						|
        create = """  JSObject* obj = JS_NewObject(aCx, &Class.mBase, proto, %s);
 | 
						|
  if (!obj) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
 | 
						|
"""
 | 
						|
    return create % parent
 | 
						|
 | 
						|
class CGWrapWithCacheMethod(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        assert descriptor.interface.hasInterfacePrototypeObject()
 | 
						|
        args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
 | 
						|
                Argument(descriptor.nativeType + '*', 'aObject'),
 | 
						|
                Argument('nsWrapperCache*', 'aCache'),
 | 
						|
                Argument('bool*', 'aTriedToWrap')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        if self.descriptor.workers:
 | 
						|
            return """  *aTriedToWrap = true;
 | 
						|
  return aObject->GetJSObject();"""
 | 
						|
 | 
						|
        return """  *aTriedToWrap = true;
 | 
						|
 | 
						|
  JSObject* parent = WrapNativeParent(aCx, aScope, aObject->GetParentObject());
 | 
						|
  if (!parent) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  JSAutoCompartment ac(aCx, parent);
 | 
						|
  JSObject* global = JS_GetGlobalForObject(aCx, parent);
 | 
						|
%s
 | 
						|
  JSObject* proto = GetProtoObject(aCx, global, global);
 | 
						|
  if (!proto) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
%s
 | 
						|
  NS_ADDREF(aObject);
 | 
						|
 | 
						|
  aCache->SetWrapper(obj);
 | 
						|
 | 
						|
  return obj;""" % (CheckPref(self.descriptor, "global", "*aTriedToWrap", "NULL", "aCache"),
 | 
						|
                    CreateBindingJSObject(self.descriptor, "parent"))
 | 
						|
 | 
						|
class CGWrapMethod(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        # XXX can we wrap if we don't have an interface prototype object?
 | 
						|
        assert descriptor.interface.hasInterfacePrototypeObject()
 | 
						|
        args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
 | 
						|
                Argument('T*', 'aObject'), Argument('bool*', 'aTriedToWrap')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args, inline=True, templateArgs=["class T"])
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        return "  return Wrap(aCx, aScope, aObject, aObject, aTriedToWrap);"
 | 
						|
 | 
						|
class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        # XXX can we wrap if we don't have an interface prototype object?
 | 
						|
        assert descriptor.interface.hasInterfacePrototypeObject()
 | 
						|
        args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
 | 
						|
                Argument(descriptor.nativeType + '*', 'aObject')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        return """
 | 
						|
  JSObject* global = JS_GetGlobalForObject(aCx, aScope);
 | 
						|
  JSObject* proto = GetProtoObject(aCx, global, global);
 | 
						|
  if (!proto) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
%s
 | 
						|
  NS_ADDREF(aObject);
 | 
						|
 | 
						|
  return obj;""" % CreateBindingJSObject(self.descriptor, "global")
 | 
						|
 | 
						|
builtinNames = {
 | 
						|
    IDLType.Tags.bool: 'bool',
 | 
						|
    IDLType.Tags.int8: 'int8_t',
 | 
						|
    IDLType.Tags.int16: 'int16_t',
 | 
						|
    IDLType.Tags.int32: 'int32_t',
 | 
						|
    IDLType.Tags.int64: 'int64_t',
 | 
						|
    IDLType.Tags.uint8: 'uint8_t',
 | 
						|
    IDLType.Tags.uint16: 'uint16_t',
 | 
						|
    IDLType.Tags.uint32: 'uint32_t',
 | 
						|
    IDLType.Tags.uint64: 'uint64_t',
 | 
						|
    IDLType.Tags.float: 'float',
 | 
						|
    IDLType.Tags.double: 'double'
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
    based on the passed-in descriptor and storing it in a variable
 | 
						|
    called by the name in the "target" argument.
 | 
						|
 | 
						|
    codeOnFailure is the code to run if unwrapping fails.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, source, target, codeOnFailure):
 | 
						|
        assert descriptor.castable
 | 
						|
 | 
						|
        self.substitution = { "type" : descriptor.nativeType,
 | 
						|
                              "protoID" : "prototypes::id::" + descriptor.name,
 | 
						|
                              "source" : source,
 | 
						|
                              "target" : target,
 | 
						|
                              "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define() }
 | 
						|
        if descriptor.hasXPConnectImpls:
 | 
						|
            # We don't use xpc_qsUnwrapThis because it will always throw on
 | 
						|
            # unwrap failure, whereas we want to control whether we throw or
 | 
						|
            # not.
 | 
						|
            self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
 | 
						|
                "${type} *objPtr;\n"
 | 
						|
                "xpc_qsSelfRef objRef;\n"
 | 
						|
                "JS::Value val = JS::ObjectValue(*${source});\n"
 | 
						|
                "nsresult rv = xpc_qsUnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
 | 
						|
                "if (NS_FAILED(rv)) {\n"
 | 
						|
                "${codeOnFailure}\n"
 | 
						|
                "}\n"
 | 
						|
                "// We should be castable!\n"
 | 
						|
                "MOZ_ASSERT(!objRef.ptr);\n"
 | 
						|
                "// We should have an object, too!\n"
 | 
						|
                "MOZ_ASSERT(objPtr);\n"
 | 
						|
                "${target} = objPtr;").substitute(self.substitution)), 4).define()
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return string.Template(
 | 
						|
"""{
 | 
						|
  nsresult rv = UnwrapObject<${protoID}, ${type}>(cx, ${source}, ${target});
 | 
						|
  if (NS_FAILED(rv)) {
 | 
						|
${codeOnFailure}
 | 
						|
  }
 | 
						|
}""").substitute(self.substitution)
 | 
						|
 | 
						|
class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
 | 
						|
    """
 | 
						|
    As CastableObjectUnwrapper, but defaulting to throwing if unwrapping fails
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, source, target):
 | 
						|
        CastableObjectUnwrapper.__init__(self, descriptor, source, target,
 | 
						|
                                         "return Throw<%s>(cx, rv);" %
 | 
						|
                                         toStringBool(not descriptor.workers))
 | 
						|
 | 
						|
class CallbackObjectUnwrapper:
 | 
						|
    """
 | 
						|
    A class for unwrapping objects implemented in JS.
 | 
						|
 | 
						|
    |source| is the JSObject we want to use in native code.
 | 
						|
    |target| is an nsCOMPtr of the appropriate type in which we store the result.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, source, target, codeOnFailure=None):
 | 
						|
        if codeOnFailure is None:
 | 
						|
            codeOnFailure = ("return Throw<%s>(cx, rv);" %
 | 
						|
                             toStringBool(not descriptor.workers))
 | 
						|
        self.descriptor = descriptor
 | 
						|
        self.substitution = { "nativeType" : descriptor.nativeType,
 | 
						|
                              "source" : source,
 | 
						|
                              "target" : target,
 | 
						|
                              "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure)).define() }
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        if self.descriptor.workers:
 | 
						|
            return string.Template(
 | 
						|
                "${target} = ${source};"
 | 
						|
                ).substitute(self.substitution)
 | 
						|
 | 
						|
        return string.Template(
 | 
						|
            """nsresult rv;
 | 
						|
XPCCallContext ccx(JS_CALLER, cx);
 | 
						|
if (!ccx.IsValid()) {
 | 
						|
  rv = NS_ERROR_XPC_BAD_CONVERT_JS;
 | 
						|
${codeOnFailure}
 | 
						|
}
 | 
						|
 | 
						|
const nsIID& iid = NS_GET_IID(${nativeType});
 | 
						|
nsRefPtr<nsXPCWrappedJS> wrappedJS;
 | 
						|
rv = nsXPCWrappedJS::GetNewOrUsed(ccx, ${source}, iid,
 | 
						|
                                  NULL, getter_AddRefs(wrappedJS));
 | 
						|
if (NS_FAILED(rv) || !wrappedJS) {
 | 
						|
${codeOnFailure}
 | 
						|
}
 | 
						|
 | 
						|
// Use a temp nsCOMPtr for the null-check, because ${target} might be
 | 
						|
// OwningNonNull, not an nsCOMPtr.
 | 
						|
nsCOMPtr<${nativeType}> tmp = do_QueryObject(wrappedJS.get());
 | 
						|
if (!tmp) {
 | 
						|
${codeOnFailure}
 | 
						|
}
 | 
						|
${target} = tmp.forget();""").substitute(self.substitution)
 | 
						|
 | 
						|
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,
 | 
						|
                                    isOptional=False,
 | 
						|
                                    invalidEnumValueFatal=True,
 | 
						|
                                    defaultValue=None,
 | 
						|
                                    treatNullAs="Default",
 | 
						|
                                    treatUndefinedAs="Default",
 | 
						|
                                    isEnforceRange=False,
 | 
						|
                                    isClamp=False):
 | 
						|
    """
 | 
						|
    Get a template for converting a JS value to a native object based on the
 | 
						|
    given type and descriptor.  If failureCode is given, then we're actually
 | 
						|
    testing whether we can convert the argument to the desired type.  That
 | 
						|
    means that failures to convert due to the JS value being the wrong type of
 | 
						|
    value need to use failureCode instead of throwing exceptions.  Failures to
 | 
						|
    convert that are due to JS exceptions (from toString or valueOf methods) or
 | 
						|
    out of memory conditions need to throw exceptions no matter what
 | 
						|
    failureCode is.
 | 
						|
 | 
						|
    If isDefinitelyObject is True, that means we know the value
 | 
						|
    isObject() and we have no need to recheck that.
 | 
						|
 | 
						|
    if isMember is True, we're being converted from a property of some
 | 
						|
    JS object, not from an actual method argument, so we can't rely on
 | 
						|
    our jsval being rooted or outliving us in any way.  Any caller
 | 
						|
    passing true needs to ensure that it is handled correctly in
 | 
						|
    typeIsSequenceOrHasSequenceMember.
 | 
						|
 | 
						|
    If isOptional is true, then we are doing conversion of an optional
 | 
						|
    argument with no default value.
 | 
						|
 | 
						|
    invalidEnumValueFatal controls whether an invalid enum value conversion
 | 
						|
    attempt will throw (if true) or simply return without doing anything (if
 | 
						|
    false).
 | 
						|
 | 
						|
    If defaultValue is not None, it's the IDL default value for this conversion
 | 
						|
 | 
						|
    If isEnforceRange is true, we're converting an integer and throwing if the
 | 
						|
    value is out of range.
 | 
						|
 | 
						|
    If isClamp is true, we're converting an integer and clamping if the
 | 
						|
    value is out of range.
 | 
						|
 | 
						|
    The return value from this function is a tuple consisting of four things:
 | 
						|
 | 
						|
    1)  A string representing the conversion code.  This will have template
 | 
						|
        substitution performed on it as follows:
 | 
						|
 | 
						|
          ${val} replaced by an expression for the JS::Value in question
 | 
						|
          ${valPtr} is a pointer to the JS::Value in question
 | 
						|
          ${holderName} replaced by the holder's name, if any
 | 
						|
          ${declName} replaced by the declaration's name
 | 
						|
          ${haveValue} replaced by an expression that evaluates to a boolean
 | 
						|
                       for whether we have a JS::Value.  Only used when
 | 
						|
                       defaultValue is not None.
 | 
						|
 | 
						|
    2)  A CGThing representing the native C++ type we're converting to
 | 
						|
        (declType).  This is allowed to be None if the conversion code is
 | 
						|
        supposed to be used as-is.
 | 
						|
    3)  A CGThing representing the type of a "holder" (holderType) which will
 | 
						|
        hold a possible reference to the C++ thing whose type we returned in #1,
 | 
						|
        or None if no such holder is needed.
 | 
						|
    4)  A boolean indicating whether the caller has to do optional-argument handling.
 | 
						|
        This will only be true if isOptional is true and if the returned template
 | 
						|
        expects both declType and holderType to be wrapped in Optional<>, with
 | 
						|
        ${declName} and ${holderName} adjusted to point to the Value() of the
 | 
						|
        Optional, and Construct() calls to be made on the Optional<>s as needed.
 | 
						|
 | 
						|
    ${declName} must be in scope before the generated code is entered.
 | 
						|
 | 
						|
    If holderType is not None then ${holderName} must be in scope
 | 
						|
    before the generated code is entered.
 | 
						|
    """
 | 
						|
    # If we have a defaultValue then we're not actually optional for
 | 
						|
    # purposes of what we need to be declared as.
 | 
						|
    assert(defaultValue is None or not isOptional)
 | 
						|
 | 
						|
    # Also, we should not have a defaultValue if we know we're an object
 | 
						|
    assert(not isDefinitelyObject or defaultValue is None)
 | 
						|
 | 
						|
    # Helper functions for dealing with failures due to the JS value being the
 | 
						|
    # wrong type of value
 | 
						|
    def onFailureNotAnObject(failureCode):
 | 
						|
        return CGWrapper(CGGeneric(
 | 
						|
                failureCode or
 | 
						|
                'return ThrowErrorMessage(cx, MSG_NOT_OBJECT);'), post="\n")
 | 
						|
    def onFailureBadType(failureCode, typeName):
 | 
						|
        return CGWrapper(CGGeneric(
 | 
						|
                failureCode or
 | 
						|
                'return ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' % typeName), post="\n")
 | 
						|
 | 
						|
    # A helper function for handling default values.  Takes a template
 | 
						|
    # body and the C++ code to set the default value and wraps the
 | 
						|
    # given template body in handling for the default value.
 | 
						|
    def handleDefault(template, setDefault):
 | 
						|
        if defaultValue is None:
 | 
						|
            return template
 | 
						|
        return CGWrapper(
 | 
						|
            CGIndenter(CGGeneric(template)),
 | 
						|
            pre="if (${haveValue}) {\n",
 | 
						|
            post=("\n"
 | 
						|
                  "} else {\n"
 | 
						|
                  "%s;\n"
 | 
						|
                  "}" %
 | 
						|
                  CGIndenter(CGGeneric(setDefault)).define())).define()
 | 
						|
 | 
						|
    # A helper function for handling null default values.  Much like
 | 
						|
    # handleDefault, but checks that the default value, if it exists, is null.
 | 
						|
    def handleDefaultNull(template, codeToSetNull):
 | 
						|
        if (defaultValue is not None and
 | 
						|
            not isinstance(defaultValue, IDLNullValue)):
 | 
						|
            raise TypeError("Can't handle non-null default value here")
 | 
						|
        return handleDefault(template, codeToSetNull)
 | 
						|
 | 
						|
    # A helper function for wrapping up the template body for
 | 
						|
    # possibly-nullable objecty stuff
 | 
						|
    def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
 | 
						|
                           codeToSetNull, failureCode=None):
 | 
						|
        if not isDefinitelyObject:
 | 
						|
            # Handle the non-object cases by wrapping up the whole
 | 
						|
            # thing in an if cascade.
 | 
						|
            templateBody = (
 | 
						|
                "if (${val}.isObject()) {\n" +
 | 
						|
                CGIndenter(CGGeneric(templateBody)).define() + "\n")
 | 
						|
            if type.nullable():
 | 
						|
                templateBody += (
 | 
						|
                    "} else if (${val}.isNullOrUndefined()) {\n"
 | 
						|
                    "  %s;\n" % codeToSetNull)
 | 
						|
            templateBody += (
 | 
						|
                "} else {\n" +
 | 
						|
                CGIndenter(onFailureNotAnObject(failureCode)).define() +
 | 
						|
                "}")
 | 
						|
            if type.nullable():
 | 
						|
                templateBody = handleDefaultNull(templateBody, codeToSetNull)
 | 
						|
            else:
 | 
						|
                assert(defaultValue is None)
 | 
						|
 | 
						|
        return templateBody
 | 
						|
 | 
						|
    assert not (isEnforceRange and isClamp) # These are mutually exclusive
 | 
						|
 | 
						|
    if type.isArray():
 | 
						|
        raise TypeError("Can't handle array arguments yet")
 | 
						|
 | 
						|
    if type.isSequence():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
 | 
						|
        if failureCode is not None:
 | 
						|
            raise TypeError("Can't handle sequences when failureCode is not None")
 | 
						|
        nullable = type.nullable();
 | 
						|
        # Be very careful not to change "type": we need it later
 | 
						|
        if nullable:
 | 
						|
            elementType = type.inner.inner
 | 
						|
        else:
 | 
						|
            elementType = type.inner
 | 
						|
 | 
						|
        # We have to be careful with reallocation behavior for arrays.  In
 | 
						|
        # particular, if we have a sequence of elements which are themselves
 | 
						|
        # sequences (so nsAutoTArrays) or have sequences as members, we have a
 | 
						|
        # problem.  In that case, resizing the outermost nsAutoTarray to the
 | 
						|
        # right size will memmove its elements, but nsAutoTArrays are not
 | 
						|
        # memmovable and hence will end up with pointers to bogus memory, which
 | 
						|
        # is bad.  To deal with this, we disallow sequences, arrays,
 | 
						|
        # dictionaries, and unions which contain sequences as sequence item
 | 
						|
        # types.  If WebIDL ever adds another container type, we'd have to
 | 
						|
        # disallow it as well.
 | 
						|
        if typeIsSequenceOrHasSequenceMember(elementType):
 | 
						|
            raise TypeError("Can't handle a sequence containing another "
 | 
						|
                            "sequence as an element or member of an element.  "
 | 
						|
                            "See the big comment explaining why.\n%s" %
 | 
						|
                            str(type.location))
 | 
						|
 | 
						|
        (elementTemplate, elementDeclType,
 | 
						|
         elementHolderType, dealWithOptional) = getJSToNativeConversionTemplate(
 | 
						|
            elementType, descriptorProvider, isMember=True)
 | 
						|
        if dealWithOptional:
 | 
						|
            raise TypeError("Shouldn't have optional things in sequences")
 | 
						|
        if elementHolderType is not None:
 | 
						|
            raise TypeError("Shouldn't need holders for sequences")
 | 
						|
 | 
						|
        typeName = CGWrapper(elementDeclType, pre="Sequence< ", post=" >")
 | 
						|
        if nullable:
 | 
						|
            typeName = CGWrapper(typeName, pre="Nullable< ", post=" >")
 | 
						|
            arrayRef = "${declName}.Value()"
 | 
						|
        else:
 | 
						|
            arrayRef = "${declName}"
 | 
						|
        # If we're optional, the const will come from the Optional
 | 
						|
        mutableTypeName = typeName
 | 
						|
        if not isOptional:
 | 
						|
            typeName = CGWrapper(typeName, pre="const ")
 | 
						|
 | 
						|
        templateBody = ("""JSObject* seq = &${val}.toObject();\n
 | 
						|
if (!IsArrayLike(cx, seq)) {
 | 
						|
  return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
 | 
						|
}
 | 
						|
uint32_t length;
 | 
						|
// JS_GetArrayLength actually works on all objects
 | 
						|
if (!JS_GetArrayLength(cx, seq, &length)) {
 | 
						|
  return false;
 | 
						|
}
 | 
						|
Sequence< %s > &arr = const_cast< Sequence< %s >& >(%s);
 | 
						|
if (!arr.SetCapacity(length)) {
 | 
						|
  return Throw<%s>(cx, NS_ERROR_OUT_OF_MEMORY);
 | 
						|
}
 | 
						|
for (uint32_t i = 0; i < length; ++i) {
 | 
						|
  jsval temp;
 | 
						|
  if (!JS_GetElement(cx, seq, i, &temp)) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
""" % (toStringBool(descriptorProvider.workers),
 | 
						|
       elementDeclType.define(),
 | 
						|
       elementDeclType.define(),
 | 
						|
       arrayRef,
 | 
						|
       toStringBool(descriptorProvider.workers)))
 | 
						|
 | 
						|
        templateBody += CGIndenter(CGGeneric(
 | 
						|
                string.Template(elementTemplate).substitute(
 | 
						|
                    {
 | 
						|
                        "val" : "temp",
 | 
						|
                        "valPtr": "&temp",
 | 
						|
                        "declName" : "(*arr.AppendElement())"
 | 
						|
                        }
 | 
						|
                    ))).define()
 | 
						|
 | 
						|
        templateBody += "\n}"
 | 
						|
        templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
 | 
						|
                                          type,
 | 
						|
                                          "const_cast< %s & >(${declName}).SetNull()" % mutableTypeName.define())
 | 
						|
        return (templateBody, typeName, None, isOptional)
 | 
						|
 | 
						|
    if type.isUnion():
 | 
						|
        if isMember:
 | 
						|
            raise TypeError("Can't handle unions as members, we have a "
 | 
						|
                            "holderType")
 | 
						|
        nullable = type.nullable();
 | 
						|
        if nullable:
 | 
						|
            type = type.inner
 | 
						|
 | 
						|
        assert(defaultValue is None or
 | 
						|
               (isinstance(defaultValue, IDLNullValue) and nullable))
 | 
						|
 | 
						|
        unionArgumentObj = "${holderName}"
 | 
						|
        if isOptional or nullable:
 | 
						|
            unionArgumentObj += ".ref()"
 | 
						|
 | 
						|
        memberTypes = type.flatMemberTypes
 | 
						|
        names = []
 | 
						|
 | 
						|
        interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
 | 
						|
        if len(interfaceMemberTypes) > 0:
 | 
						|
            interfaceObject = []
 | 
						|
            for memberType in interfaceMemberTypes:
 | 
						|
                if type.isGeckoInterface():
 | 
						|
                    name = memberType.inner.identifier.name
 | 
						|
                else:
 | 
						|
                    name = memberType.name
 | 
						|
                interfaceObject.append(CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext" % (unionArgumentObj, name)))
 | 
						|
                names.append(name)
 | 
						|
            interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"), pre="done = ", post=";\n", reindent=True)
 | 
						|
        else:
 | 
						|
            interfaceObject = None
 | 
						|
 | 
						|
        arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
 | 
						|
        if len(arrayObjectMemberTypes) > 0:
 | 
						|
            assert len(arrayObjectMemberTypes) == 1
 | 
						|
            memberType = arrayObjectMemberTypes[0]
 | 
						|
            name = memberType.name
 | 
						|
            arrayObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
 | 
						|
            # XXX Now we're supposed to check for an array or a platform object
 | 
						|
            # that supports indexed properties... skip that last for now. It's a
 | 
						|
            # bit of a pain.
 | 
						|
            arrayObject = CGWrapper(CGIndenter(arrayObject),
 | 
						|
                                    pre="if (IsArrayLike(cx, &argObj)) {\n",
 | 
						|
                                    post="}")
 | 
						|
            names.append(name)
 | 
						|
        else:
 | 
						|
            arrayObject = None
 | 
						|
 | 
						|
        dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
 | 
						|
        if len(dateObjectMemberTypes) > 0:
 | 
						|
            assert len(dateObjectMemberTypes) == 1
 | 
						|
            memberType = dateObjectMemberTypes[0]
 | 
						|
            name = memberType.name
 | 
						|
            dateObject = CGGeneric("%s.SetTo%s(cx, ${val}, ${valPtr});\n"
 | 
						|
                                   "done = true;" % (unionArgumentObj, name))
 | 
						|
            dateObject = CGWrapper(CGIndenter(dateObject),
 | 
						|
                                   pre="if (JS_ObjectIsDate(cx, &argObj)) {\n",
 | 
						|
                                   post="\n}")
 | 
						|
            names.append(name)
 | 
						|
        else:
 | 
						|
            dateObject = None
 | 
						|
 | 
						|
        callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
 | 
						|
        if len(callbackMemberTypes) > 0:
 | 
						|
            assert len(callbackMemberTypes) == 1
 | 
						|
            memberType = callbackMemberTypes[0]
 | 
						|
            name = memberType.name
 | 
						|
            callbackObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
 | 
						|
            names.append(name)
 | 
						|
        else:
 | 
						|
            callbackObject = None
 | 
						|
 | 
						|
        dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
 | 
						|
        if len(dictionaryMemberTypes) > 0:
 | 
						|
            raise TypeError("No support for unwrapping dictionaries as member "
 | 
						|
                            "of a union")
 | 
						|
        else:
 | 
						|
            dictionaryObject = None
 | 
						|
 | 
						|
        if callbackObject or dictionaryObject:
 | 
						|
            nonPlatformObject = CGList([callbackObject, dictionaryObject], "\n")
 | 
						|
            nonPlatformObject = CGWrapper(CGIndenter(nonPlatformObject),
 | 
						|
                                          pre="if (!IsPlatformObject(cx, &argObj)) {\n",
 | 
						|
                                          post="\n}")
 | 
						|
        else:
 | 
						|
            nonPlatformObject = None
 | 
						|
 | 
						|
        objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
 | 
						|
        if len(objectMemberTypes) > 0:
 | 
						|
            object = CGGeneric("%s.SetToObject(&argObj);\n"
 | 
						|
                               "done = true;" % unionArgumentObj)
 | 
						|
        else:
 | 
						|
            object = None
 | 
						|
 | 
						|
        hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object
 | 
						|
        if hasObjectTypes:
 | 
						|
            # If we try more specific object types first then we need to check
 | 
						|
            # whether that succeeded before converting to object.
 | 
						|
            if object and (interfaceObject or arrayObject or dateObject or nonPlatformObject):
 | 
						|
                object = CGWrapper(CGIndenter(object), pre="if (!done) {\n",
 | 
						|
                                   post=("\n}"))
 | 
						|
 | 
						|
            if arrayObject or dateObject or nonPlatformObject:
 | 
						|
                # An object can be both an array object and not a platform
 | 
						|
                # object, but we shouldn't have both in the union's members
 | 
						|
                # because they are not distinguishable.
 | 
						|
                assert not (arrayObject and nonPlatformObject)
 | 
						|
                templateBody = CGList([arrayObject, dateObject, nonPlatformObject], " else ")
 | 
						|
            else:
 | 
						|
                templateBody = None
 | 
						|
            if interfaceObject:
 | 
						|
                if templateBody:
 | 
						|
                    templateBody = CGList([templateBody, object], "\n")
 | 
						|
                    templateBody = CGWrapper(CGIndenter(templateBody),
 | 
						|
                                             pre="if (!done) {\n", post=("\n}"))
 | 
						|
                templateBody = CGList([interfaceObject, templateBody], "\n")
 | 
						|
            else:
 | 
						|
                templateBody = CGList([templateBody, object], "\n")
 | 
						|
 | 
						|
            if any([arrayObject, dateObject, nonPlatformObject, object]):
 | 
						|
                templateBody.prepend(CGGeneric("JSObject& argObj = ${val}.toObject();"))
 | 
						|
            templateBody = CGWrapper(CGIndenter(templateBody),
 | 
						|
                                     pre="if (${val}.isObject()) {\n",
 | 
						|
                                     post="\n}")
 | 
						|
        else:
 | 
						|
            templateBody = CGGeneric()
 | 
						|
 | 
						|
        otherMemberTypes = filter(lambda t: t.isString() or t.isEnum(),
 | 
						|
                                  memberTypes)
 | 
						|
        otherMemberTypes.extend(t for t in memberTypes if t.isPrimitive())
 | 
						|
        if len(otherMemberTypes) > 0:
 | 
						|
            assert len(otherMemberTypes) == 1
 | 
						|
            memberType = otherMemberTypes[0]
 | 
						|
            if memberType.isEnum():
 | 
						|
                name = memberType.inner.identifier.name
 | 
						|
            else:
 | 
						|
                name = memberType.name
 | 
						|
            other = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
 | 
						|
            names.append(name)
 | 
						|
            if hasObjectTypes:
 | 
						|
                other = CGWrapper(CGIndenter(other), "{\n", post="\n}")
 | 
						|
                if object:
 | 
						|
                    join = " else "
 | 
						|
                else:
 | 
						|
                    other = CGWrapper(other, pre="if (!done) ")
 | 
						|
                    join = "\n"
 | 
						|
                templateBody = CGList([templateBody, other], join)
 | 
						|
        else:
 | 
						|
            other = None
 | 
						|
 | 
						|
        templateBody = CGWrapper(templateBody, pre="bool done = false, failed = false, tryNext;\n")
 | 
						|
        throw = CGGeneric("if (failed) {\n"
 | 
						|
                          "  return false;\n"
 | 
						|
                          "}\n"
 | 
						|
                          "if (!done) {\n"
 | 
						|
                          "  return ThrowErrorMessage(cx, MSG_NOT_IN_UNION, \"%s\");\n"
 | 
						|
                          "}" % ", ".join(names))
 | 
						|
        templateBody = CGWrapper(CGIndenter(CGList([templateBody, throw], "\n")), pre="{\n", post="\n}")
 | 
						|
 | 
						|
        typeName = type.name
 | 
						|
        argumentTypeName = typeName + "Argument"
 | 
						|
        if nullable:
 | 
						|
            typeName = "Nullable<" + typeName + " >"
 | 
						|
        if isOptional:
 | 
						|
            nonConstDecl = "const_cast<Optional<" + typeName + " >& >(${declName})"
 | 
						|
        else:
 | 
						|
            nonConstDecl = "const_cast<" + typeName + "& >(${declName})"
 | 
						|
            typeName = "const " + typeName
 | 
						|
 | 
						|
        def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
 | 
						|
            null = CGGeneric("if (%s${val}.isNullOrUndefined()) {\n"
 | 
						|
                             "  %s.SetNull();\n"
 | 
						|
                             "}" % (extraConditionForNull, setToNullVar))
 | 
						|
            templateBody = CGWrapper(CGIndenter(templateBody), pre="{\n", post="\n}")
 | 
						|
            return CGList([null, templateBody], " else ")
 | 
						|
 | 
						|
        if type.hasNullableType:
 | 
						|
            templateBody = handleNull(templateBody, unionArgumentObj)
 | 
						|
 | 
						|
        declType = CGGeneric(typeName)
 | 
						|
        holderType = CGGeneric(argumentTypeName)
 | 
						|
        if isOptional:
 | 
						|
            mutableDecl = nonConstDecl + ".Value()"
 | 
						|
            declType = CGWrapper(declType, pre="const Optional<", post=" >")
 | 
						|
            holderType = CGWrapper(holderType, pre="Maybe<", post=" >")
 | 
						|
            constructDecl = CGGeneric(nonConstDecl + ".Construct();")
 | 
						|
            if nullable:
 | 
						|
                constructHolder = CGGeneric("${holderName}.construct(%s.SetValue());" % mutableDecl)
 | 
						|
            else:
 | 
						|
                constructHolder = CGGeneric("${holderName}.construct(${declName}.Value());")
 | 
						|
        else:
 | 
						|
            mutableDecl = nonConstDecl
 | 
						|
            constructDecl = None
 | 
						|
            if nullable:
 | 
						|
                holderType = CGWrapper(holderType, pre="Maybe<", post=" >")
 | 
						|
                constructHolder = CGGeneric("${holderName}.construct(%s.SetValue());" % mutableDecl)
 | 
						|
            else:
 | 
						|
                constructHolder = CGWrapper(holderType, post=" ${holderName}(${declName});")
 | 
						|
                holderType = None
 | 
						|
 | 
						|
        templateBody = CGList([constructHolder, templateBody], "\n")
 | 
						|
        if nullable:
 | 
						|
            if defaultValue:
 | 
						|
                assert(isinstance(defaultValue, IDLNullValue))
 | 
						|
                valueMissing = "!(${haveValue}) || "
 | 
						|
            else:
 | 
						|
                valueMissing = ""
 | 
						|
            templateBody = handleNull(templateBody, mutableDecl,
 | 
						|
                                      extraConditionForNull=valueMissing)
 | 
						|
        templateBody = CGList([constructDecl, templateBody], "\n")
 | 
						|
 | 
						|
        return templateBody.define(), declType, holderType, False
 | 
						|
 | 
						|
    if type.isGeckoInterface():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
 | 
						|
        descriptor = descriptorProvider.getDescriptor(
 | 
						|
            type.unroll().inner.identifier.name)
 | 
						|
        # This is an interface that we implement as a concrete class
 | 
						|
        # or an XPCOM interface.
 | 
						|
 | 
						|
        # Allow null pointers for nullable types and old-binding classes
 | 
						|
        argIsPointer = type.nullable() or type.unroll().inner.isExternal()
 | 
						|
 | 
						|
        # Sequences and non-worker callbacks have to hold a strong ref to the
 | 
						|
        # thing being passed down.
 | 
						|
        forceOwningType = (descriptor.interface.isCallback() and
 | 
						|
                           not descriptor.workers) or isMember
 | 
						|
 | 
						|
        typeName = descriptor.nativeType
 | 
						|
        typePtr = typeName + "*"
 | 
						|
 | 
						|
        # Compute a few things:
 | 
						|
        #  - declType is the type we want to return as the first element of our
 | 
						|
        #    tuple.
 | 
						|
        #  - holderType is the type we want to return as the third element
 | 
						|
        #    of our tuple.
 | 
						|
 | 
						|
        # Set up some sensible defaults for these things insofar as we can.
 | 
						|
        holderType = None
 | 
						|
        if argIsPointer:
 | 
						|
            if forceOwningType:
 | 
						|
                declType = "nsRefPtr<" + typeName + ">"
 | 
						|
            else:
 | 
						|
                declType = typePtr
 | 
						|
        else:
 | 
						|
            if forceOwningType:
 | 
						|
                declType = "OwningNonNull<" + typeName + ">"
 | 
						|
            else:
 | 
						|
                declType = "NonNull<" + typeName + ">"
 | 
						|
 | 
						|
        templateBody = ""
 | 
						|
        if descriptor.castable:
 | 
						|
            if descriptor.prefable:
 | 
						|
                raise TypeError("We don't support prefable castable object "
 | 
						|
                                "arguments (like %s), because we don't know "
 | 
						|
                                "how to handle them being preffed off" %
 | 
						|
                                descriptor.interface.identifier.name)
 | 
						|
            if descriptor.interface.isConsequential():
 | 
						|
                raise TypeError("Consequential interface %s being used as an "
 | 
						|
                                "argument but flagged as castable" %
 | 
						|
                                descriptor.interface.identifier.name)
 | 
						|
            if failureCode is not None:
 | 
						|
                templateBody += str(CastableObjectUnwrapper(
 | 
						|
                        descriptor,
 | 
						|
                        "&${val}.toObject()",
 | 
						|
                        "${declName}",
 | 
						|
                        failureCode))
 | 
						|
            else:
 | 
						|
                templateBody += str(FailureFatalCastableObjectUnwrapper(
 | 
						|
                        descriptor,
 | 
						|
                        "&${val}.toObject()",
 | 
						|
                        "${declName}"))
 | 
						|
        elif descriptor.interface.isCallback():
 | 
						|
            templateBody += str(CallbackObjectUnwrapper(
 | 
						|
                    descriptor,
 | 
						|
                    "&${val}.toObject()",
 | 
						|
                    "${declName}",
 | 
						|
                    codeOnFailure=failureCode))
 | 
						|
        elif descriptor.workers:
 | 
						|
            templateBody += "${declName} = &${val}.toObject();"
 | 
						|
        else:
 | 
						|
            # Either external, or new-binding non-castable.  We always have a
 | 
						|
            # holder for these, because we don't actually know whether we have
 | 
						|
            # to addref when unwrapping or not.  So we just pass an
 | 
						|
            # getter_AddRefs(nsRefPtr) to XPConnect and if we'll need a release
 | 
						|
            # it'll put a non-null pointer in there.
 | 
						|
            if forceOwningType:
 | 
						|
                # Don't return a holderType in this case; our declName
 | 
						|
                # will just own stuff.
 | 
						|
                templateBody += "nsRefPtr<" + typeName + "> ${holderName};\n"
 | 
						|
            else:
 | 
						|
                holderType = "nsRefPtr<" + typeName + ">"
 | 
						|
            templateBody += (
 | 
						|
                "jsval tmpVal = ${val};\n" +
 | 
						|
                typePtr + " tmp;\n"
 | 
						|
                "if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), &tmpVal))) {\n")
 | 
						|
            templateBody += CGIndenter(onFailureBadType(failureCode,
 | 
						|
                                                        descriptor.interface.identifier.name)).define()
 | 
						|
            templateBody += ("}\n"
 | 
						|
                "MOZ_ASSERT(tmp);\n")
 | 
						|
 | 
						|
            if not isDefinitelyObject:
 | 
						|
                # Our tmpVal will go out of scope, so we can't rely on it
 | 
						|
                # for rooting
 | 
						|
                templateBody += (
 | 
						|
                    "if (tmpVal != ${val} && !${holderName}) {\n"
 | 
						|
                    "  // We have to have a strong ref, because we got this off\n"
 | 
						|
                    "  // some random object that might get GCed\n"
 | 
						|
                    "  ${holderName} = tmp;\n"
 | 
						|
                    "}\n")
 | 
						|
 | 
						|
            # And store our tmp, before it goes out of scope.
 | 
						|
            templateBody += "${declName} = tmp;"
 | 
						|
 | 
						|
        templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
 | 
						|
                                          type, "${declName} = NULL",
 | 
						|
                                          failureCode)
 | 
						|
 | 
						|
        declType = CGGeneric(declType)
 | 
						|
        if holderType is not None:
 | 
						|
            holderType = CGGeneric(holderType)
 | 
						|
        return (templateBody, declType, holderType, isOptional)
 | 
						|
 | 
						|
    if type.isSpiderMonkeyInterface():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
        if isMember:
 | 
						|
            raise TypeError("Can't handle member arraybuffers or "
 | 
						|
                            "arraybuffer views because making sure all the "
 | 
						|
                            "objects are properly rooted is hard")
 | 
						|
        name = type.name
 | 
						|
        # By default, we use a Maybe<> to hold our typed array.  And in the optional
 | 
						|
        # non-nullable case we want to pass Optional<TypedArray> to consumers, not
 | 
						|
        # Optional<NonNull<TypedArray> >, so jump though some hoops to do that.
 | 
						|
        holderType = "Maybe<%s>" % name
 | 
						|
        constructLoc = "${holderName}"
 | 
						|
        constructMethod = "construct"
 | 
						|
        constructInternal = "ref"
 | 
						|
        if type.nullable():
 | 
						|
            if isOptional:
 | 
						|
                declType = "const Optional<" + name + "*>"
 | 
						|
            else:
 | 
						|
                declType = name + "*"
 | 
						|
        else:
 | 
						|
            if isOptional:
 | 
						|
                declType = "const Optional<" + name + ">"
 | 
						|
                # We don't need a holder in this case
 | 
						|
                holderType = None
 | 
						|
                constructLoc = "(const_cast<Optional<" + name + ">& >(${declName}))"
 | 
						|
                constructMethod = "Construct"
 | 
						|
                constructInternal = "Value"
 | 
						|
            else:
 | 
						|
                declType = "NonNull<" + name + ">"
 | 
						|
        template = (
 | 
						|
            "%s.%s(cx, &${val}.toObject());\n"
 | 
						|
            "if (!%s.%s().inited()) {\n"
 | 
						|
            "%s" # No newline here because onFailureBadType() handles that
 | 
						|
            "}\n" %
 | 
						|
            (constructLoc, constructMethod, constructLoc, constructInternal,
 | 
						|
             CGIndenter(onFailureBadType(failureCode, type.name)).define()))
 | 
						|
        nullableTarget = ""
 | 
						|
        if type.nullable():
 | 
						|
            if isOptional:
 | 
						|
                mutableDecl = "(const_cast<Optional<" + name + "*>& >(${declName}))"
 | 
						|
                template += "%s.Construct();\n" % mutableDecl
 | 
						|
                nullableTarget = "%s.Value()" % mutableDecl
 | 
						|
            else:
 | 
						|
                nullableTarget = "${declName}"
 | 
						|
            template += "%s = ${holderName}.addr();" % nullableTarget
 | 
						|
        elif not isOptional:
 | 
						|
            template += "${declName} = ${holderName}.addr();"
 | 
						|
        template = wrapObjectTemplate(template, isDefinitelyObject, type,
 | 
						|
                                      "%s = NULL" % nullableTarget,
 | 
						|
                                      failureCode)
 | 
						|
 | 
						|
        if holderType is not None:
 | 
						|
            holderType = CGGeneric(holderType)
 | 
						|
        # We handle all the optional stuff ourselves; no need for caller to do it.
 | 
						|
        return (template, CGGeneric(declType), holderType, False)
 | 
						|
 | 
						|
    if type.isString():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
 | 
						|
        treatAs = {
 | 
						|
            "Default": "eStringify",
 | 
						|
            "EmptyString": "eEmpty",
 | 
						|
            "Null": "eNull"
 | 
						|
        }
 | 
						|
        if type.nullable():
 | 
						|
            # For nullable strings null becomes a null string.
 | 
						|
            treatNullAs = "Null"
 | 
						|
            # For nullable strings undefined becomes a null string unless
 | 
						|
            # specified otherwise.
 | 
						|
            if treatUndefinedAs == "Default":
 | 
						|
                treatUndefinedAs = "Null"
 | 
						|
        nullBehavior = treatAs[treatNullAs]
 | 
						|
        if treatUndefinedAs == "Missing":
 | 
						|
            raise TypeError("We don't support [TreatUndefinedAs=Missing]")
 | 
						|
        undefinedBehavior = treatAs[treatUndefinedAs]
 | 
						|
 | 
						|
        def getConversionCode(varName):
 | 
						|
            conversionCode = (
 | 
						|
                "if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, %s)) {\n"
 | 
						|
                "  return false;\n"
 | 
						|
                "}" % (nullBehavior, undefinedBehavior, varName))
 | 
						|
            if defaultValue is None:
 | 
						|
                return conversionCode
 | 
						|
 | 
						|
            if isinstance(defaultValue, IDLNullValue):
 | 
						|
                assert(type.nullable())
 | 
						|
                return handleDefault(conversionCode,
 | 
						|
                                     "%s.SetNull()" % varName)
 | 
						|
            return handleDefault(
 | 
						|
                conversionCode,
 | 
						|
                ("static const PRUnichar data[] = { %s };\n"
 | 
						|
                 "%s.SetData(data, ArrayLength(data) - 1)" %
 | 
						|
                 (", ".join(["'" + char + "'" for char in defaultValue.value] + ["0"]),
 | 
						|
                  varName)))
 | 
						|
 | 
						|
        if isMember:
 | 
						|
            # We have to make a copy, because our jsval may well not
 | 
						|
            # live as long as our string needs to.
 | 
						|
            declType = CGGeneric("nsString")
 | 
						|
            return (
 | 
						|
                "{\n"
 | 
						|
                "  FakeDependentString str;\n"
 | 
						|
                "%s\n"
 | 
						|
                "  ${declName} = str;\n"
 | 
						|
                "}\n" % CGIndenter(CGGeneric(getConversionCode("str"))).define(),
 | 
						|
                declType, None, isOptional)
 | 
						|
 | 
						|
        if isOptional:
 | 
						|
            declType = "Optional<nsAString>"
 | 
						|
        else:
 | 
						|
            declType = "NonNull<nsAString>"
 | 
						|
 | 
						|
        return (
 | 
						|
            "%s\n"
 | 
						|
            "const_cast<%s&>(${declName}) = &${holderName};" %
 | 
						|
            (getConversionCode("${holderName}"), declType),
 | 
						|
            CGGeneric("const " + declType), CGGeneric("FakeDependentString"),
 | 
						|
            # No need to deal with Optional here; we have handled it already
 | 
						|
            False)
 | 
						|
 | 
						|
    if type.isEnum():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
 | 
						|
        if type.nullable():
 | 
						|
            raise TypeError("We don't support nullable enumerated arguments "
 | 
						|
                            "yet")
 | 
						|
        enum = type.inner.identifier.name
 | 
						|
        if invalidEnumValueFatal:
 | 
						|
            handleInvalidEnumValueCode = "  MOZ_ASSERT(index >= 0);\n"
 | 
						|
        else:
 | 
						|
            handleInvalidEnumValueCode = (
 | 
						|
                "  if (index < 0) {\n"
 | 
						|
                "    return true;\n"
 | 
						|
                "  }\n")
 | 
						|
            
 | 
						|
        template = (
 | 
						|
            "{\n"
 | 
						|
            "  bool ok;\n"
 | 
						|
            "  int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, \"%(enumtype)s\", &ok);\n"
 | 
						|
            "  if (!ok) {\n"
 | 
						|
            "    return false;\n"
 | 
						|
            "  }\n"
 | 
						|
            "%(handleInvalidEnumValueCode)s"
 | 
						|
            "  ${declName} = static_cast<%(enumtype)s>(index);\n"
 | 
						|
            "}" % { "enumtype" : enum,
 | 
						|
                      "values" : enum + "Values::strings",
 | 
						|
       "invalidEnumValueFatal" : toStringBool(invalidEnumValueFatal),
 | 
						|
  "handleInvalidEnumValueCode" : handleInvalidEnumValueCode })
 | 
						|
 | 
						|
        if defaultValue is not None:
 | 
						|
            assert(defaultValue.type.tag() == IDLType.Tags.domstring)
 | 
						|
            template = handleDefault(template,
 | 
						|
                                     ("${declName} = %sValues::%s" %
 | 
						|
                                      (enum,
 | 
						|
                                       getEnumValueName(defaultValue.value))))
 | 
						|
        return (template, CGGeneric(enum), None, isOptional)
 | 
						|
 | 
						|
    if type.isCallback():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
 | 
						|
        if isMember:
 | 
						|
            raise TypeError("Can't handle member callbacks; need to sort out "
 | 
						|
                            "rooting issues")
 | 
						|
        # XXXbz we're going to assume that callback types are always
 | 
						|
        # nullable and always have [TreatNonCallableAsNull] for now.
 | 
						|
        haveCallable = "${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())"
 | 
						|
        if defaultValue is not None:
 | 
						|
            assert(isinstance(defaultValue, IDLNullValue))
 | 
						|
            haveCallable = "${haveValue} && " + haveCallable
 | 
						|
        return (
 | 
						|
            "if (%s) {\n"
 | 
						|
            "  ${declName} = &${val}.toObject();\n"
 | 
						|
            "} else {\n"
 | 
						|
            "  ${declName} = NULL;\n"
 | 
						|
            "}" % haveCallable,
 | 
						|
            CGGeneric("JSObject*"), None, isOptional)
 | 
						|
 | 
						|
    if type.isAny():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
 | 
						|
        if isMember:
 | 
						|
            raise TypeError("Can't handle member 'any'; need to sort out "
 | 
						|
                            "rooting issues")
 | 
						|
        templateBody = "${declName} = ${val};"
 | 
						|
        templateBody = handleDefaultNull(templateBody,
 | 
						|
                                         "${declName} = JS::NullValue()")
 | 
						|
        return (templateBody, CGGeneric("JS::Value"), None, isOptional)
 | 
						|
 | 
						|
    if type.isObject():
 | 
						|
        assert not isEnforceRange and not isClamp
 | 
						|
 | 
						|
        if isMember:
 | 
						|
            raise TypeError("Can't handle member 'object'; need to sort out "
 | 
						|
                            "rooting issues")
 | 
						|
        template = wrapObjectTemplate("${declName} = &${val}.toObject();",
 | 
						|
                                      isDefinitelyObject, type,
 | 
						|
                                      "${declName} = NULL",
 | 
						|
                                      failureCode)
 | 
						|
        if type.nullable():
 | 
						|
            declType = CGGeneric("JSObject*")
 | 
						|
        else:
 | 
						|
            declType = CGGeneric("NonNull<JSObject>")
 | 
						|
        return (template, declType, None, isOptional)
 | 
						|
 | 
						|
    if type.isDictionary():
 | 
						|
        if failureCode is not None:
 | 
						|
            raise TypeError("Can't handle dictionaries when failureCode is not None")
 | 
						|
        # There are no nullable dictionaries
 | 
						|
        assert not type.nullable()
 | 
						|
        # All optional dictionaries always have default values, so we
 | 
						|
        # should be able to assume not isOptional here.
 | 
						|
        assert not isOptional
 | 
						|
 | 
						|
        typeName = CGDictionary.makeDictionaryName(type.inner,
 | 
						|
                                                   descriptorProvider.workers)
 | 
						|
        actualTypeName = typeName
 | 
						|
        selfRef = "${declName}"
 | 
						|
 | 
						|
        declType = CGGeneric(actualTypeName)
 | 
						|
 | 
						|
        # If we're a member of something else, the const
 | 
						|
        # will come from the Optional or our container.
 | 
						|
        if not isMember:
 | 
						|
            declType = CGWrapper(declType, pre="const ")
 | 
						|
            selfRef = "const_cast<%s&>(%s)" % (typeName, selfRef)
 | 
						|
 | 
						|
        # We do manual default value handling here, because we
 | 
						|
        # actually do want a jsval, and we only handle null anyway
 | 
						|
        if defaultValue is not None:
 | 
						|
            assert(isinstance(defaultValue, IDLNullValue))
 | 
						|
            val = "(${haveValue}) ? ${val} : JSVAL_NULL"
 | 
						|
        else:
 | 
						|
            val = "${val}"
 | 
						|
 | 
						|
        template = ("if (!%s.Init(cx, %s)) {\n"
 | 
						|
                    "  return false;\n"
 | 
						|
                    "}" % (selfRef, val))
 | 
						|
 | 
						|
        return (template, declType, None, False)
 | 
						|
 | 
						|
    if not type.isPrimitive():
 | 
						|
        raise TypeError("Need conversion for argument type '%s'" % str(type))
 | 
						|
 | 
						|
    typeName = builtinNames[type.tag()]
 | 
						|
 | 
						|
    conversionBehavior = "eDefault"
 | 
						|
    if isEnforceRange:
 | 
						|
        conversionBehavior = "eEnforceRange"
 | 
						|
    elif isClamp:
 | 
						|
        conversionBehavior = "eClamp"
 | 
						|
 | 
						|
    if type.nullable():
 | 
						|
        dataLoc = "${declName}.SetValue()"
 | 
						|
        nullCondition = "${val}.isNullOrUndefined()"
 | 
						|
        if defaultValue is not None and isinstance(defaultValue, IDLNullValue):
 | 
						|
            nullCondition = "!(${haveValue}) || " + nullCondition
 | 
						|
        template = (
 | 
						|
            "if (%s) {\n"
 | 
						|
            "  ${declName}.SetNull();\n"
 | 
						|
            "} else if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
 | 
						|
            "  return false;\n"
 | 
						|
            "}" % (nullCondition, typeName, conversionBehavior, dataLoc))
 | 
						|
        declType = CGGeneric("Nullable<" + typeName + ">")
 | 
						|
    else:
 | 
						|
        assert(defaultValue is None or
 | 
						|
               not isinstance(defaultValue, IDLNullValue))
 | 
						|
        dataLoc = "${declName}"
 | 
						|
        template = (
 | 
						|
            "if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
 | 
						|
            "  return false;\n"
 | 
						|
            "}" % (typeName, conversionBehavior, dataLoc))
 | 
						|
        declType = CGGeneric(typeName)
 | 
						|
    if (defaultValue is not None and
 | 
						|
        # We already handled IDLNullValue, so just deal with the other ones
 | 
						|
        not isinstance(defaultValue, IDLNullValue)):
 | 
						|
        tag = defaultValue.type.tag()
 | 
						|
        if tag in numericTags:
 | 
						|
            defaultStr = defaultValue.value
 | 
						|
        else:
 | 
						|
            assert(tag == IDLType.Tags.bool)
 | 
						|
            defaultStr = toStringBool(defaultValue.value)
 | 
						|
        template = CGWrapper(CGIndenter(CGGeneric(template)),
 | 
						|
                             pre="if (${haveValue}) {\n",
 | 
						|
                             post=("\n"
 | 
						|
                                   "} else {\n"
 | 
						|
                                   "  %s = %s;\n"
 | 
						|
                                   "}" % (dataLoc, defaultStr))).define()
 | 
						|
 | 
						|
    return (template, declType, None, isOptional)
 | 
						|
 | 
						|
def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
 | 
						|
                                            argcAndIndex=None):
 | 
						|
    """
 | 
						|
    Take a tuple as returned by getJSToNativeConversionTemplate and a set of
 | 
						|
    replacements as required by the strings in such a tuple, and generate code
 | 
						|
    to convert into stack C++ types.
 | 
						|
 | 
						|
    If argcAndIndex is not None it must be a dict that can be used to
 | 
						|
    replace ${argc} and ${index}, where ${index} is the index of this
 | 
						|
    argument (0-based) and ${argc} is the total number of arguments.
 | 
						|
    """
 | 
						|
    (templateBody, declType, holderType, dealWithOptional) = templateTuple
 | 
						|
 | 
						|
    if dealWithOptional and argcAndIndex is None:
 | 
						|
        raise TypeError("Have to deal with optional things, but don't know how")
 | 
						|
    if argcAndIndex is not None and declType is None:
 | 
						|
        raise TypeError("Need to predeclare optional things, so they will be "
 | 
						|
                        "outside the check for big enough arg count!");
 | 
						|
 | 
						|
    result = CGList([], "\n")
 | 
						|
    # Make a copy of "replacements" since we may be about to start modifying it
 | 
						|
    replacements = dict(replacements)
 | 
						|
    originalHolderName = replacements["holderName"]
 | 
						|
    if holderType is not None:
 | 
						|
        if dealWithOptional:
 | 
						|
            replacements["holderName"] = (
 | 
						|
                "const_cast< %s & >(%s.Value())" %
 | 
						|
                (holderType.define(), originalHolderName))
 | 
						|
            mutableHolderType = CGWrapper(holderType, pre="Optional< ", post=" >")
 | 
						|
            holderType = CGWrapper(mutableHolderType, pre="const ")
 | 
						|
        result.append(
 | 
						|
            CGList([holderType, CGGeneric(" "),
 | 
						|
                    CGGeneric(originalHolderName),
 | 
						|
                    CGGeneric(";")]))
 | 
						|
 | 
						|
    originalDeclName = replacements["declName"]
 | 
						|
    if declType is not None:
 | 
						|
        if dealWithOptional:
 | 
						|
            replacements["declName"] = (
 | 
						|
                "const_cast< %s & >(%s.Value())" %
 | 
						|
                (declType.define(), originalDeclName))
 | 
						|
            mutableDeclType = CGWrapper(declType, pre="Optional< ", post=" >")
 | 
						|
            declType = CGWrapper(mutableDeclType, pre="const ")
 | 
						|
        result.append(
 | 
						|
            CGList([declType, CGGeneric(" "),
 | 
						|
                    CGGeneric(originalDeclName),
 | 
						|
                    CGGeneric(";")]))
 | 
						|
 | 
						|
    conversion = CGGeneric(
 | 
						|
            string.Template(templateBody).substitute(replacements)
 | 
						|
            )
 | 
						|
 | 
						|
    if argcAndIndex is not None:
 | 
						|
        if dealWithOptional:
 | 
						|
            declConstruct = CGIndenter(
 | 
						|
                CGGeneric("const_cast< %s &>(%s).Construct();" %
 | 
						|
                          (mutableDeclType.define(), originalDeclName)))
 | 
						|
            if holderType is not None:
 | 
						|
                holderConstruct = CGIndenter(
 | 
						|
                    CGGeneric("const_cast< %s &>(%s).Construct();" %
 | 
						|
                              (mutableHolderType.define(), originalHolderName)))
 | 
						|
            else:
 | 
						|
                holderConstruct = None
 | 
						|
        else:
 | 
						|
            declConstruct = None
 | 
						|
            holderConstruct = None
 | 
						|
 | 
						|
        conversion = CGList(
 | 
						|
            [CGGeneric(
 | 
						|
                    string.Template("if (${index} < ${argc}) {").substitute(
 | 
						|
                        argcAndIndex
 | 
						|
                        )),
 | 
						|
             declConstruct,
 | 
						|
             holderConstruct,
 | 
						|
             CGIndenter(conversion),
 | 
						|
             CGGeneric("}")],
 | 
						|
            "\n")
 | 
						|
 | 
						|
    result.append(conversion)
 | 
						|
    # Add an empty CGGeneric to get an extra newline after the argument
 | 
						|
    # conversion.
 | 
						|
    result.append(CGGeneric(""))
 | 
						|
    return result;
 | 
						|
 | 
						|
def convertConstIDLValueToJSVal(value):
 | 
						|
    if isinstance(value, IDLNullValue):
 | 
						|
        return "JSVAL_NULL"
 | 
						|
    tag = value.type.tag()
 | 
						|
    if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
 | 
						|
               IDLType.Tags.uint16, IDLType.Tags.int32]:
 | 
						|
        return "INT_TO_JSVAL(%s)" % (value.value)
 | 
						|
    if tag == IDLType.Tags.uint32:
 | 
						|
        return "UINT_TO_JSVAL(%s)" % (value.value)
 | 
						|
    if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
 | 
						|
        return "DOUBLE_TO_JSVAL(%s)" % (value.value)
 | 
						|
    if tag == IDLType.Tags.bool:
 | 
						|
        return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
 | 
						|
    if tag in [IDLType.Tags.float, IDLType.Tags.double]:
 | 
						|
        return "DOUBLE_TO_JSVAL(%s)" % (value.value)
 | 
						|
    raise TypeError("Const value of unhandled type: " + value.type)
 | 
						|
 | 
						|
class CGArgumentConverter(CGThing):
 | 
						|
    """
 | 
						|
    A class that takes an IDL argument object, its index in the
 | 
						|
    argument list, and the argv and argc strings and generates code to
 | 
						|
    unwrap the argument to the right native type.
 | 
						|
    """
 | 
						|
    def __init__(self, argument, index, argv, argc, descriptorProvider,
 | 
						|
                 invalidEnumValueFatal=True):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.argument = argument
 | 
						|
        if argument.variadic:
 | 
						|
            raise TypeError("We don't support variadic arguments yet " +
 | 
						|
                            str(argument.location))
 | 
						|
        assert(not argument.defaultValue or argument.optional)
 | 
						|
 | 
						|
        replacer = {
 | 
						|
            "index" : index,
 | 
						|
            "argc" : argc,
 | 
						|
            "argv" : argv
 | 
						|
            }
 | 
						|
        self.replacementVariables = {
 | 
						|
            "declName" : "arg%d" % index,
 | 
						|
            "holderName" : ("arg%d" % index) + "_holder"
 | 
						|
            }
 | 
						|
        self.replacementVariables["val"] = string.Template(
 | 
						|
            "${argv}[${index}]"
 | 
						|
            ).substitute(replacer)
 | 
						|
        self.replacementVariables["valPtr"] = (
 | 
						|
            "&" + self.replacementVariables["val"])
 | 
						|
        if argument.defaultValue:
 | 
						|
            self.replacementVariables["haveValue"] = string.Template(
 | 
						|
                "${index} < ${argc}").substitute(replacer)
 | 
						|
        self.descriptorProvider = descriptorProvider
 | 
						|
        if self.argument.optional and not self.argument.defaultValue:
 | 
						|
            self.argcAndIndex = replacer
 | 
						|
        else:
 | 
						|
            self.argcAndIndex = None
 | 
						|
        self.invalidEnumValueFatal = invalidEnumValueFatal
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return instantiateJSToNativeConversionTemplate(
 | 
						|
            getJSToNativeConversionTemplate(self.argument.type,
 | 
						|
                                            self.descriptorProvider,
 | 
						|
                                            isOptional=(self.argcAndIndex is not None),
 | 
						|
                                            invalidEnumValueFatal=self.invalidEnumValueFatal,
 | 
						|
                                            defaultValue=self.argument.defaultValue,
 | 
						|
                                            treatNullAs=self.argument.treatNullAs,
 | 
						|
                                            treatUndefinedAs=self.argument.treatUndefinedAs,
 | 
						|
                                            isEnforceRange=self.argument.enforceRange,
 | 
						|
                                            isClamp=self.argument.clamp),
 | 
						|
            self.replacementVariables,
 | 
						|
            self.argcAndIndex).define()
 | 
						|
 | 
						|
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
 | 
						|
                           isCreator):
 | 
						|
    """
 | 
						|
    Reflect a C++ value stored in "result", of IDL type "type" into JS.  The
 | 
						|
    "successCode" is the code to run once we have successfully done the
 | 
						|
    conversion.  The resulting string should be used with string.Template, it
 | 
						|
    needs the following keys when substituting: jsvalPtr/jsvalRef/obj.
 | 
						|
 | 
						|
    Returns (templateString, infallibility of conversion template)
 | 
						|
    """
 | 
						|
    haveSuccessCode = successCode is not None
 | 
						|
    if not haveSuccessCode:
 | 
						|
        successCode = "return true;"
 | 
						|
 | 
						|
    def setValue(value, callWrapValue=False):
 | 
						|
        """
 | 
						|
        Returns the code to set the jsval to value. If "callWrapValue" is true
 | 
						|
        JS_WrapValue will be called on the jsval.
 | 
						|
        """
 | 
						|
        if not callWrapValue:
 | 
						|
            tail = successCode
 | 
						|
        elif haveSuccessCode:
 | 
						|
            tail = ("if (!JS_WrapValue(cx, ${jsvalPtr})) {\n" +
 | 
						|
                    "  return false;\n" +
 | 
						|
                    "}\n" +
 | 
						|
                    successCode)
 | 
						|
        else:
 | 
						|
            tail = "return JS_WrapValue(cx, ${jsvalPtr});"
 | 
						|
        return ("${jsvalRef} = %s;\n" +
 | 
						|
                tail) % (value)
 | 
						|
 | 
						|
    def wrapAndSetPtr(wrapCall, failureCode=None):
 | 
						|
        """
 | 
						|
        Returns the code to set the jsval by calling "wrapCall". "failureCode"
 | 
						|
        is the code to run if calling "wrapCall" fails 
 | 
						|
        """
 | 
						|
        if failureCode is None:
 | 
						|
            if not haveSuccessCode:
 | 
						|
                return "return " + wrapCall + ";"
 | 
						|
            failureCode = "return false;"
 | 
						|
        str = ("if (!%s) {\n" +
 | 
						|
               CGIndenter(CGGeneric(failureCode)).define() + "\n" +
 | 
						|
               "}\n" +
 | 
						|
               successCode) % (wrapCall)
 | 
						|
        return str
 | 
						|
    
 | 
						|
    if type is None or type.isVoid():
 | 
						|
        return (setValue("JSVAL_VOID"), True)
 | 
						|
 | 
						|
    if type.isArray():
 | 
						|
        raise TypeError("Can't handle array return values yet")
 | 
						|
 | 
						|
    if type.isSequence():
 | 
						|
        if type.nullable():
 | 
						|
            # Nullable sequences are Nullable< nsTArray<T> >
 | 
						|
            (recTemplate, recInfall) = getWrapTemplateForType(type.inner, descriptorProvider,
 | 
						|
                                                              "%s.Value()" % result, successCode,
 | 
						|
                                                              isCreator)
 | 
						|
            return ("""
 | 
						|
if (%s.IsNull()) {
 | 
						|
%s
 | 
						|
}
 | 
						|
%s""" % (result, CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define(), recTemplate), recInfall)
 | 
						|
 | 
						|
        # Now do non-nullable sequences.  We use setting the element
 | 
						|
        # in the array as our succcess code because when we succeed in
 | 
						|
        # wrapping that's what we should do.
 | 
						|
        innerTemplate = wrapForType(
 | 
						|
            type.inner, descriptorProvider,
 | 
						|
            {
 | 
						|
                'result' :  "%s[i]" % result,
 | 
						|
                'successCode': ("if (!JS_DefineElement(cx, returnArray, i, tmp,\n"
 | 
						|
                                "                      NULL, NULL, JSPROP_ENUMERATE)) {\n"
 | 
						|
                                "  return false;\n"
 | 
						|
                                "}"),
 | 
						|
                'jsvalRef': "tmp",
 | 
						|
                'jsvalPtr': "&tmp",
 | 
						|
                'isCreator': isCreator
 | 
						|
                }
 | 
						|
            )
 | 
						|
        innerTemplate = CGIndenter(CGGeneric(innerTemplate)).define()
 | 
						|
        return (("""
 | 
						|
uint32_t length = %s.Length();
 | 
						|
JSObject *returnArray = JS_NewArrayObject(cx, length, NULL);
 | 
						|
if (!returnArray) {
 | 
						|
  return false;
 | 
						|
}
 | 
						|
jsval tmp;
 | 
						|
for (uint32_t i = 0; i < length; ++i) {
 | 
						|
%s
 | 
						|
}\n""" % (result, innerTemplate)) + setValue("JS::ObjectValue(*returnArray)"), False)
 | 
						|
 | 
						|
    if type.isGeckoInterface():
 | 
						|
        descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
 | 
						|
        if type.nullable():
 | 
						|
            wrappingCode = ("if (!%s) {\n" % (result) +
 | 
						|
                            CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
 | 
						|
                            "}\n")
 | 
						|
        else:
 | 
						|
            wrappingCode = ""
 | 
						|
        if (not descriptor.interface.isExternal() and
 | 
						|
            not descriptor.interface.isCallback()):
 | 
						|
            if descriptor.wrapperCache:
 | 
						|
                wrapMethod = "WrapNewBindingObject"
 | 
						|
            else:
 | 
						|
                if not isCreator:
 | 
						|
                    raise MethodNotCreatorError(descriptor.interface.identifier.name)
 | 
						|
                wrapMethod = "WrapNewBindingNonWrapperCachedObject"
 | 
						|
            wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, result)
 | 
						|
            # We don't support prefable stuff in workers.
 | 
						|
            assert(not descriptor.prefable or not descriptor.workers)
 | 
						|
            if not descriptor.prefable:
 | 
						|
                # Non-prefable bindings can only fail to wrap as a new-binding object
 | 
						|
                # if they already threw an exception.  Same thing for
 | 
						|
                # non-prefable bindings.
 | 
						|
                failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
 | 
						|
                          "return false;")
 | 
						|
            else:
 | 
						|
                if descriptor.notflattened:
 | 
						|
                    raise TypeError("%s is prefable but not flattened; "
 | 
						|
                                    "fallback won't work correctly" %
 | 
						|
                                    descriptor.interface.identifier.name)
 | 
						|
                # Try old-style wrapping for bindings which might be preffed off.
 | 
						|
                failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
 | 
						|
            wrappingCode += wrapAndSetPtr(wrap, failed)
 | 
						|
        else:
 | 
						|
            if descriptor.notflattened:
 | 
						|
                getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
 | 
						|
            else:
 | 
						|
                getIID = ""
 | 
						|
            wrap = "WrapObject(cx, ${obj}, %s, %s${jsvalPtr})" % (result, getIID)
 | 
						|
            wrappingCode += wrapAndSetPtr(wrap)
 | 
						|
        return (wrappingCode, False)
 | 
						|
 | 
						|
    if type.isString():
 | 
						|
        if type.nullable():
 | 
						|
            return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalPtr})" % result), False)
 | 
						|
        else:
 | 
						|
            return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalPtr})" % result), False)
 | 
						|
 | 
						|
    if type.isEnum():
 | 
						|
        if type.nullable():
 | 
						|
            raise TypeError("We don't support nullable enumerated return types "
 | 
						|
                            "yet")
 | 
						|
        return ("""MOZ_ASSERT(uint32_t(%(result)s) < ArrayLength(%(strings)s));
 | 
						|
JSString* %(resultStr)s = JS_NewStringCopyN(cx, %(strings)s[uint32_t(%(result)s)].value, %(strings)s[uint32_t(%(result)s)].length);
 | 
						|
if (!%(resultStr)s) {
 | 
						|
  return false;
 | 
						|
}
 | 
						|
""" % { "result" : result,
 | 
						|
        "resultStr" : result + "_str",
 | 
						|
        "strings" : type.inner.identifier.name + "Values::strings" } +
 | 
						|
        setValue("JS::StringValue(%s_str)" % result), False)
 | 
						|
 | 
						|
    if type.isCallback():
 | 
						|
        assert not type.isInterface()
 | 
						|
        # XXXbz we're going to assume that callback types are always
 | 
						|
        # nullable and always have [TreatNonCallableAsNull] for now.
 | 
						|
        # See comments in WrapNewBindingObject explaining why we need
 | 
						|
        # to wrap here.
 | 
						|
        # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
 | 
						|
        return (setValue("JS::ObjectOrNullValue(%s)" % result, True), False)
 | 
						|
 | 
						|
    if type.tag() == IDLType.Tags.any:
 | 
						|
        # See comments in WrapNewBindingObject explaining why we need
 | 
						|
        # to wrap here.
 | 
						|
        # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
 | 
						|
        return (setValue(result, True), False)
 | 
						|
 | 
						|
    if type.isObject() or type.isSpiderMonkeyInterface():
 | 
						|
        # See comments in WrapNewBindingObject explaining why we need
 | 
						|
        # to wrap here.
 | 
						|
        if type.nullable():
 | 
						|
            toValue = "JS::ObjectOrNullValue(%s)"
 | 
						|
        else:
 | 
						|
            toValue = "JS::ObjectValue(*%s)"
 | 
						|
        # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
 | 
						|
        return (setValue(toValue % result, True), False)
 | 
						|
 | 
						|
    if not type.isPrimitive():
 | 
						|
        raise TypeError("Need to learn to wrap %s" % type)
 | 
						|
 | 
						|
    if type.nullable():
 | 
						|
        (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider,
 | 
						|
                                                         "%s.Value()" % result, successCode,
 | 
						|
                                                         isCreator)
 | 
						|
        return ("if (%s.IsNull()) {\n" % result +
 | 
						|
                CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
 | 
						|
                "}\n" + recTemplate, recInfal)
 | 
						|
    
 | 
						|
    tag = type.tag()
 | 
						|
    
 | 
						|
    if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
 | 
						|
               IDLType.Tags.uint16, IDLType.Tags.int32]:
 | 
						|
        return (setValue("INT_TO_JSVAL(int32_t(%s))" % result), True)
 | 
						|
 | 
						|
    elif tag in [IDLType.Tags.int64, IDLType.Tags.uint64, IDLType.Tags.float,
 | 
						|
                 IDLType.Tags.double]:
 | 
						|
        # XXXbz will cast to double do the "even significand" thing that webidl
 | 
						|
        # calls for for 64-bit ints?  Do we care?
 | 
						|
        return (setValue("JS_NumberValue(double(%s))" % result), True)
 | 
						|
 | 
						|
    elif tag == IDLType.Tags.uint32:
 | 
						|
        return (setValue("UINT_TO_JSVAL(%s)" % result), True)
 | 
						|
 | 
						|
    elif tag == IDLType.Tags.bool:
 | 
						|
        return (setValue("BOOLEAN_TO_JSVAL(%s)" % result), True)
 | 
						|
 | 
						|
    else:
 | 
						|
        raise TypeError("Need to learn to wrap primitive: %s" % type)
 | 
						|
 | 
						|
def wrapForType(type, descriptorProvider, templateValues):
 | 
						|
    """
 | 
						|
    Reflect a C++ value of IDL type "type" into JS.  TemplateValues is a dict
 | 
						|
    that should contain:
 | 
						|
 | 
						|
      * 'jsvalRef': a C++ reference to the jsval in which to store the result of
 | 
						|
                    the conversion
 | 
						|
      * 'jsvalPtr': a C++ pointer to the jsval in which to store the result of
 | 
						|
                    the conversion
 | 
						|
      * 'obj' (optional): the name of the variable that contains the JSObject to
 | 
						|
                          use as a scope when wrapping, if not supplied 'obj'
 | 
						|
                          will be used as the name
 | 
						|
      * 'result' (optional): the name of the variable in which the C++ value is
 | 
						|
                             stored, if not supplied 'result' will be used as
 | 
						|
                             the name
 | 
						|
      * 'successCode' (optional): the code to run once we have successfully done
 | 
						|
                                  the conversion, if not supplied 'return true;'
 | 
						|
                                  will be used as the code
 | 
						|
      * 'isCreator' (optional): If true, we're wrapping for the return value of
 | 
						|
                                a [Creator] method.  Assumed false if not set.
 | 
						|
    """
 | 
						|
    wrap = getWrapTemplateForType(type, descriptorProvider,
 | 
						|
                                  templateValues.get('result', 'result'),
 | 
						|
                                  templateValues.get('successCode', None),
 | 
						|
                                  templateValues.get('isCreator', False))[0]
 | 
						|
 | 
						|
    defaultValues = {'obj': 'obj'}
 | 
						|
    return string.Template(wrap).substitute(defaultValues, **templateValues)
 | 
						|
 | 
						|
def infallibleForMember(member, type, descriptorProvider):
 | 
						|
    """
 | 
						|
    Determine the fallibility of changing a C++ value of IDL type "type" into
 | 
						|
    JS for the given attribute. Apart from isCreator, all the defaults are used,
 | 
						|
    since the fallbility does not change based on the boolean values,
 | 
						|
    and the template will be discarded.
 | 
						|
 | 
						|
    CURRENT ASSUMPTIONS:
 | 
						|
        We assume that successCode for wrapping up return values cannot contain
 | 
						|
        failure conditions.
 | 
						|
    """
 | 
						|
    return getWrapTemplateForType(type, descriptorProvider, 'result', None,\
 | 
						|
                                  memberIsCreator(member))[1]
 | 
						|
 | 
						|
def typeNeedsCx(type, retVal=False):
 | 
						|
    if type is None:
 | 
						|
        return False
 | 
						|
    if type.nullable():
 | 
						|
        type = type.inner
 | 
						|
    if type.isSequence() or type.isArray():
 | 
						|
        type = type.inner
 | 
						|
    if type.isUnion():
 | 
						|
        return any(typeNeedsCx(t) for t in type.unroll().flatMemberTypes)
 | 
						|
    if retVal and type.isSpiderMonkeyInterface():
 | 
						|
        return True
 | 
						|
    return type.isCallback() or type.isAny() or type.isObject()
 | 
						|
 | 
						|
# Returns a tuple consisting of a CGThing containing the type of the return
 | 
						|
# value, or None if there is no need for a return value, and a boolean signaling
 | 
						|
# whether the return value is passed in an out parameter.
 | 
						|
def getRetvalDeclarationForType(returnType, descriptorProvider,
 | 
						|
                                resultAlreadyAddRefed):
 | 
						|
    if returnType is None or returnType.isVoid():
 | 
						|
        # Nothing to declare
 | 
						|
        return None, False
 | 
						|
    if returnType.isPrimitive() and returnType.tag() in builtinNames:
 | 
						|
        result = CGGeneric(builtinNames[returnType.tag()])
 | 
						|
        if returnType.nullable():
 | 
						|
            result = CGWrapper(result, pre="Nullable<", post=">")
 | 
						|
        return result, False
 | 
						|
    if returnType.isString():
 | 
						|
        return CGGeneric("nsString"), True
 | 
						|
    if returnType.isEnum():
 | 
						|
        if returnType.nullable():
 | 
						|
            raise TypeError("We don't support nullable enum return values")
 | 
						|
        return CGGeneric(returnType.inner.identifier.name), False
 | 
						|
    if returnType.isGeckoInterface():
 | 
						|
        result = CGGeneric(descriptorProvider.getDescriptor(
 | 
						|
            returnType.unroll().inner.identifier.name).nativeType)
 | 
						|
        if resultAlreadyAddRefed:
 | 
						|
            result = CGWrapper(result, pre="nsRefPtr<", post=">")
 | 
						|
        else:
 | 
						|
            result = CGWrapper(result, post="*")
 | 
						|
        return result, False
 | 
						|
    if returnType.isCallback():
 | 
						|
        # XXXbz we're going to assume that callback types are always
 | 
						|
        # nullable for now.
 | 
						|
        return CGGeneric("JSObject*"), False
 | 
						|
    if returnType.isAny():
 | 
						|
        return CGGeneric("JS::Value"), False
 | 
						|
    if returnType.isObject() or returnType.isSpiderMonkeyInterface():
 | 
						|
        return CGGeneric("JSObject*"), False
 | 
						|
    if returnType.isSequence():
 | 
						|
        nullable = returnType.nullable()
 | 
						|
        if nullable:
 | 
						|
            returnType = returnType.inner
 | 
						|
        # If our result is already addrefed, use the right type in the
 | 
						|
        # sequence argument here.
 | 
						|
        (result, _) = getRetvalDeclarationForType(returnType.inner,
 | 
						|
                                                  descriptorProvider,
 | 
						|
                                                  resultAlreadyAddRefed)
 | 
						|
        result = CGWrapper(result, pre="nsTArray< ", post=" >")
 | 
						|
        if nullable:
 | 
						|
            result = CGWrapper(result, pre="Nullable< ", post=" >")
 | 
						|
        return result, True
 | 
						|
    raise TypeError("Don't know how to declare return value for %s" %
 | 
						|
                    returnType)
 | 
						|
 | 
						|
def isResultAlreadyAddRefed(descriptor, extendedAttributes):
 | 
						|
    # Default to already_AddRefed on the main thread, raw pointer in workers
 | 
						|
    return not descriptor.workers and not 'resultNotAddRefed' in extendedAttributes
 | 
						|
 | 
						|
class CGCallGenerator(CGThing):
 | 
						|
    """
 | 
						|
    A class to generate an actual call to a C++ object.  Assumes that the C++
 | 
						|
    object is stored in a variable whose name is given by the |object| argument.
 | 
						|
 | 
						|
    errorReport should be a CGThing for an error report or None if no
 | 
						|
    error reporting is needed.
 | 
						|
    """
 | 
						|
    def __init__(self, errorReport, arguments, argsPre, returnType,
 | 
						|
                 extendedAttributes, descriptorProvider, nativeMethodName,
 | 
						|
                 static, object="self", declareResult=True):
 | 
						|
        CGThing.__init__(self)
 | 
						|
 | 
						|
        assert errorReport is None or isinstance(errorReport, CGThing)
 | 
						|
 | 
						|
        isFallible = errorReport is not None
 | 
						|
 | 
						|
        resultAlreadyAddRefed = isResultAlreadyAddRefed(descriptorProvider,
 | 
						|
                                                        extendedAttributes)
 | 
						|
        (result, resultOutParam) = getRetvalDeclarationForType(returnType,
 | 
						|
                                                               descriptorProvider,
 | 
						|
                                                               resultAlreadyAddRefed)
 | 
						|
 | 
						|
        args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
 | 
						|
        for (a, name) in arguments:
 | 
						|
            # This is a workaround for a bug in Apple's clang.
 | 
						|
            if a.type.isObject() and not a.type.nullable() and not a.optional:
 | 
						|
                name = "(JSObject&)" + name
 | 
						|
            args.append(CGGeneric(name))
 | 
						|
 | 
						|
        # Return values that go in outparams go here
 | 
						|
        if resultOutParam:
 | 
						|
            args.append(CGGeneric("result"))
 | 
						|
        if isFallible:
 | 
						|
            args.append(CGGeneric("rv"))
 | 
						|
 | 
						|
        needsCx = (typeNeedsCx(returnType, True) or
 | 
						|
                   any(typeNeedsCx(a.type) for (a, _) in arguments) or
 | 
						|
                   'implicitJSContext' in extendedAttributes)
 | 
						|
 | 
						|
        if not "cx" in argsPre and needsCx:
 | 
						|
            args.prepend(CGGeneric("cx"))
 | 
						|
 | 
						|
        # Build up our actual call
 | 
						|
        self.cgRoot = CGList([], "\n")
 | 
						|
 | 
						|
        call = CGGeneric(nativeMethodName)
 | 
						|
        if static:
 | 
						|
            call = CGWrapper(call, pre="%s::" % descriptorProvider.nativeType)
 | 
						|
        else: 
 | 
						|
            call = CGWrapper(call, pre="%s->" % object)
 | 
						|
        call = CGList([call, CGWrapper(args, pre="(", post=");")])
 | 
						|
        if result is not None:
 | 
						|
            if declareResult:
 | 
						|
                result = CGWrapper(result, post=" result;")
 | 
						|
                self.cgRoot.prepend(result)
 | 
						|
            if not resultOutParam:
 | 
						|
                call = CGWrapper(call, pre="result = ")
 | 
						|
 | 
						|
        call = CGWrapper(call)
 | 
						|
        self.cgRoot.append(call)
 | 
						|
 | 
						|
        if isFallible:
 | 
						|
            self.cgRoot.prepend(CGGeneric("ErrorResult rv;"))
 | 
						|
            self.cgRoot.append(CGGeneric("if (rv.Failed()) {"))
 | 
						|
            self.cgRoot.append(CGIndenter(errorReport))
 | 
						|
            self.cgRoot.append(CGGeneric("}"))
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return self.cgRoot.define()
 | 
						|
 | 
						|
class MethodNotCreatorError(Exception):
 | 
						|
    def __init__(self, typename):
 | 
						|
        self.typename = typename
 | 
						|
 | 
						|
class CGPerSignatureCall(CGThing):
 | 
						|
    """
 | 
						|
    This class handles the guts of generating code for a particular
 | 
						|
    call signature.  A call signature consists of four things:
 | 
						|
 | 
						|
    1) A return type, which can be None to indicate that there is no
 | 
						|
       actual return value (e.g. this is an attribute setter) or an
 | 
						|
       IDLType if there's an IDL type involved (including |void|).
 | 
						|
    2) An argument list, which is allowed to be empty.
 | 
						|
    3) A name of a native method to call.
 | 
						|
    4) Whether or not this method is static.
 | 
						|
 | 
						|
    We also need to know whether this is a method or a getter/setter
 | 
						|
    to do error reporting correctly.
 | 
						|
 | 
						|
    The idlNode parameter can be either a method or an attr. We can query
 | 
						|
    |idlNode.identifier| in both cases, so we can be agnostic between the two.
 | 
						|
    """
 | 
						|
    # XXXbz For now each entry in the argument list is either an
 | 
						|
    # IDLArgument or a FakeArgument, but longer-term we may want to
 | 
						|
    # have ways of flagging things like JSContext* or optional_argc in
 | 
						|
    # there.
 | 
						|
 | 
						|
    def __init__(self, returnType, argsPre, arguments, nativeMethodName, static,
 | 
						|
                 descriptor, idlNode, argConversionStartsAt=0,
 | 
						|
                 getter=False, setter=False):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.returnType = returnType
 | 
						|
        self.descriptor = descriptor
 | 
						|
        self.idlNode = idlNode
 | 
						|
        self.extendedAttributes = descriptor.getExtendedAttributes(idlNode,
 | 
						|
                                                                   getter=getter,
 | 
						|
                                                                   setter=setter)
 | 
						|
        self.argsPre = argsPre
 | 
						|
        self.arguments = arguments
 | 
						|
        self.argCount = len(arguments)
 | 
						|
        if self.argCount > argConversionStartsAt:
 | 
						|
            # Insert our argv in there
 | 
						|
            cgThings = [CGGeneric(self.getArgvDecl())]
 | 
						|
        else:
 | 
						|
            cgThings = []
 | 
						|
        cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(),
 | 
						|
                                             self.getArgc(), self.descriptor,
 | 
						|
                                             invalidEnumValueFatal=not setter) for
 | 
						|
                         i in range(argConversionStartsAt, self.argCount)])
 | 
						|
 | 
						|
        cgThings.append(CGCallGenerator(
 | 
						|
                    self.getErrorReport() if self.isFallible() else None,
 | 
						|
                    self.getArguments(), self.argsPre, returnType,
 | 
						|
                    self.extendedAttributes, descriptor, nativeMethodName,
 | 
						|
                    static))
 | 
						|
        self.cgRoot = CGList(cgThings, "\n")
 | 
						|
 | 
						|
    def getArgv(self):
 | 
						|
        return "argv" if self.argCount > 0 else ""
 | 
						|
    def getArgvDecl(self):
 | 
						|
        return "\nJS::Value* argv = JS_ARGV(cx, vp);\n"
 | 
						|
    def getArgc(self):
 | 
						|
        return "argc"
 | 
						|
    def getArguments(self):
 | 
						|
        return [(a, "arg" + str(i)) for (i, a) in enumerate(self.arguments)]
 | 
						|
 | 
						|
    def isFallible(self):
 | 
						|
        return not 'infallible' in self.extendedAttributes
 | 
						|
 | 
						|
    def wrap_return_value(self):
 | 
						|
        isCreator = memberIsCreator(self.idlNode)
 | 
						|
        if isCreator:
 | 
						|
            # We better be returning addrefed things!
 | 
						|
            assert(isResultAlreadyAddRefed(self.descriptor,
 | 
						|
                                           self.extendedAttributes) or
 | 
						|
                   # Workers use raw pointers for new-object return
 | 
						|
                   # values or something
 | 
						|
                   self.descriptor.workers)
 | 
						|
 | 
						|
        resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp',
 | 
						|
                                 'isCreator': isCreator}
 | 
						|
        try:
 | 
						|
            return wrapForType(self.returnType, self.descriptor,
 | 
						|
                               resultTemplateValues)
 | 
						|
        except MethodNotCreatorError, err:
 | 
						|
            assert not isCreator
 | 
						|
            raise TypeError("%s being returned from non-creator method or property %s.%s" %
 | 
						|
                            (err.typename,
 | 
						|
                             self.descriptor.interface.identifier.name,
 | 
						|
                             self.idlNode.identifier.name))
 | 
						|
 | 
						|
    def getErrorReport(self):
 | 
						|
        return CGGeneric('return ThrowMethodFailedWithDetails<%s>(cx, rv, "%s", "%s");'
 | 
						|
                         % (toStringBool(not self.descriptor.workers),
 | 
						|
                            self.descriptor.interface.identifier.name,
 | 
						|
                            self.idlNode.identifier.name))
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return (self.cgRoot.define() + "\n" + self.wrap_return_value())
 | 
						|
 | 
						|
class CGSwitch(CGList):
 | 
						|
    """
 | 
						|
    A class to generate code for a switch statement.
 | 
						|
 | 
						|
    Takes three constructor arguments: an expression, a list of cases,
 | 
						|
    and an optional default.
 | 
						|
 | 
						|
    Each case is a CGCase.  The default is a CGThing for the body of
 | 
						|
    the default case, if any.
 | 
						|
    """
 | 
						|
    def __init__(self, expression, cases, default=None):
 | 
						|
        CGList.__init__(self, [CGIndenter(c) for c in cases], "\n")
 | 
						|
        self.prepend(CGWrapper(CGGeneric(expression),
 | 
						|
                               pre="switch (", post=") {"));
 | 
						|
        if default is not None:
 | 
						|
            self.append(
 | 
						|
                CGIndenter(
 | 
						|
                    CGWrapper(
 | 
						|
                        CGIndenter(default),
 | 
						|
                        pre="default: {\n",
 | 
						|
                        post="\n  break;\n}"
 | 
						|
                        )
 | 
						|
                    )
 | 
						|
                )
 | 
						|
                        
 | 
						|
        self.append(CGGeneric("}"))
 | 
						|
 | 
						|
class CGCase(CGList):
 | 
						|
    """
 | 
						|
    A class to generate code for a case statement.
 | 
						|
 | 
						|
    Takes three constructor arguments: an expression, a CGThing for
 | 
						|
    the body (allowed to be None if there is no body), and an optional
 | 
						|
    argument (defaulting to False) for whether to fall through.
 | 
						|
    """
 | 
						|
    def __init__(self, expression, body, fallThrough=False):
 | 
						|
        CGList.__init__(self, [], "\n")
 | 
						|
        self.append(CGWrapper(CGGeneric(expression), pre="case ", post=": {"))
 | 
						|
        bodyList = CGList([body], "\n")
 | 
						|
        if fallThrough:
 | 
						|
            bodyList.append(CGGeneric("/* Fall through */"))
 | 
						|
        else:
 | 
						|
            bodyList.append(CGGeneric("break;"))
 | 
						|
        self.append(CGIndenter(bodyList));
 | 
						|
        self.append(CGGeneric("}"))
 | 
						|
 | 
						|
class CGMethodCall(CGThing):
 | 
						|
    """
 | 
						|
    A class to generate selection of a method signature from a set of
 | 
						|
    signatures and generation of a call to that signature.
 | 
						|
    """
 | 
						|
    def __init__(self, argsPre, nativeMethodName, static, descriptor, method):
 | 
						|
        CGThing.__init__(self)
 | 
						|
 | 
						|
        methodName = '"%s.%s"' % (descriptor.interface.identifier.name, method.identifier.name)
 | 
						|
 | 
						|
        def requiredArgCount(signature):
 | 
						|
            arguments = signature[1]
 | 
						|
            if len(arguments) == 0:
 | 
						|
                return 0
 | 
						|
            requiredArgs = len(arguments)
 | 
						|
            while requiredArgs and arguments[requiredArgs-1].optional:
 | 
						|
                requiredArgs -= 1
 | 
						|
            return requiredArgs
 | 
						|
 | 
						|
        def getPerSignatureCall(signature, argConversionStartsAt=0):
 | 
						|
            return CGPerSignatureCall(signature[0], argsPre, signature[1],
 | 
						|
                                      nativeMethodName, static, descriptor,
 | 
						|
                                      method, argConversionStartsAt)
 | 
						|
            
 | 
						|
 | 
						|
        signatures = method.signatures()
 | 
						|
        if len(signatures) == 1:
 | 
						|
            # Special case: we can just do a per-signature method call
 | 
						|
            # here for our one signature and not worry about switching
 | 
						|
            # on anything.
 | 
						|
            signature = signatures[0]
 | 
						|
            self.cgRoot = CGList([ CGIndenter(getPerSignatureCall(signature)) ])
 | 
						|
            requiredArgs = requiredArgCount(signature)
 | 
						|
 | 
						|
 | 
						|
            if requiredArgs > 0:
 | 
						|
                code = (
 | 
						|
                    "if (argc < %d) {\n"
 | 
						|
                    "  return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n"
 | 
						|
                    "}" % (requiredArgs, methodName))
 | 
						|
                self.cgRoot.prepend(
 | 
						|
                    CGWrapper(CGIndenter(CGGeneric(code)), pre="\n", post="\n"))
 | 
						|
            return
 | 
						|
 | 
						|
        # Need to find the right overload
 | 
						|
        maxArgCount = method.maxArgCount
 | 
						|
        allowedArgCounts = method.allowedArgCounts
 | 
						|
 | 
						|
        argCountCases = []
 | 
						|
        for argCount in allowedArgCounts:
 | 
						|
            possibleSignatures = method.signaturesForArgCount(argCount)
 | 
						|
            if len(possibleSignatures) == 1:
 | 
						|
                # easy case!
 | 
						|
                signature = possibleSignatures[0]
 | 
						|
 | 
						|
                # (possibly) important optimization: if signature[1] has >
 | 
						|
                # argCount arguments and signature[1][argCount] is optional and
 | 
						|
                # there is only one signature for argCount+1, then the
 | 
						|
                # signature for argCount+1 is just ourselves and we can fall
 | 
						|
                # through.
 | 
						|
                if (len(signature[1]) > argCount and
 | 
						|
                    signature[1][argCount].optional and
 | 
						|
                    (argCount+1) in allowedArgCounts and
 | 
						|
                    len(method.signaturesForArgCount(argCount+1)) == 1):
 | 
						|
                    argCountCases.append(
 | 
						|
                        CGCase(str(argCount), None, True))
 | 
						|
                else:
 | 
						|
                    argCountCases.append(
 | 
						|
                        CGCase(str(argCount), getPerSignatureCall(signature)))
 | 
						|
                continue
 | 
						|
 | 
						|
            distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
 | 
						|
 | 
						|
            # We can't handle unions at the distinguishing index.
 | 
						|
            for (returnType, args) in possibleSignatures:
 | 
						|
                if args[distinguishingIndex].type.isUnion():
 | 
						|
                    raise TypeError("No support for unions as distinguishing "
 | 
						|
                                    "arguments yet: %s",
 | 
						|
                                    args[distinguishingIndex].location)
 | 
						|
 | 
						|
            # Convert all our arguments up to the distinguishing index.
 | 
						|
            # Doesn't matter which of the possible signatures we use, since
 | 
						|
            # they all have the same types up to that point; just use
 | 
						|
            # possibleSignatures[0]
 | 
						|
            caseBody = [CGGeneric("JS::Value* argv_start = JS_ARGV(cx, vp);")]
 | 
						|
            caseBody.extend([ CGArgumentConverter(possibleSignatures[0][1][i],
 | 
						|
                                                  i, "argv_start", "argc",
 | 
						|
                                                  descriptor) for i in
 | 
						|
                              range(0, distinguishingIndex) ])
 | 
						|
 | 
						|
            # Select the right overload from our set.
 | 
						|
            distinguishingArg = "argv_start[%d]" % distinguishingIndex
 | 
						|
 | 
						|
            def pickFirstSignature(condition, filterLambda):
 | 
						|
                sigs = filter(filterLambda, possibleSignatures)
 | 
						|
                assert len(sigs) < 2
 | 
						|
                if len(sigs) > 0:
 | 
						|
                    if condition is None:
 | 
						|
                        caseBody.append(
 | 
						|
                            getPerSignatureCall(sigs[0], distinguishingIndex))
 | 
						|
                    else:
 | 
						|
                        caseBody.append(CGGeneric("if (" + condition + ") {"))
 | 
						|
                        caseBody.append(CGIndenter(
 | 
						|
                                getPerSignatureCall(sigs[0], distinguishingIndex)))
 | 
						|
                        caseBody.append(CGGeneric("}"))
 | 
						|
                    return True
 | 
						|
                return False
 | 
						|
 | 
						|
            # First check for null or undefined
 | 
						|
            pickFirstSignature("%s.isNullOrUndefined()" % distinguishingArg,
 | 
						|
                               lambda s: (s[1][distinguishingIndex].type.nullable() or
 | 
						|
                                          s[1][distinguishingIndex].type.isDictionary()))
 | 
						|
 | 
						|
            # Now check for distinguishingArg being an object that implements a
 | 
						|
            # non-callback interface.  That includes typed arrays and
 | 
						|
            # arraybuffers.
 | 
						|
            interfacesSigs = [
 | 
						|
                s for s in possibleSignatures
 | 
						|
                if (s[1][distinguishingIndex].type.isObject() or
 | 
						|
                    s[1][distinguishingIndex].type.isNonCallbackInterface()) ]
 | 
						|
            # There might be more than one of these; we need to check
 | 
						|
            # which ones we unwrap to.
 | 
						|
            
 | 
						|
            if len(interfacesSigs) > 0:
 | 
						|
                # The spec says that we should check for "platform objects
 | 
						|
                # implementing an interface", but it's enough to guard on these
 | 
						|
                # being an object.  The code for unwrapping non-callback
 | 
						|
                # interfaces and typed arrays will just bail out and move on to
 | 
						|
                # the next overload if the object fails to unwrap correctly.  We
 | 
						|
                # could even not do the isObject() check up front here, but in
 | 
						|
                # cases where we have multiple object overloads it makes sense
 | 
						|
                # to do it only once instead of for each overload.  That will
 | 
						|
                # also allow the unwrapping test to skip having to do codegen
 | 
						|
                # for the null-or-undefined case, which we already handled
 | 
						|
                # above.
 | 
						|
                caseBody.append(CGGeneric("if (%s.isObject()) {" %
 | 
						|
                                          (distinguishingArg)))
 | 
						|
                for sig in interfacesSigs:
 | 
						|
                    caseBody.append(CGIndenter(CGGeneric("do {")));
 | 
						|
                    type = sig[1][distinguishingIndex].type
 | 
						|
 | 
						|
                    # The argument at index distinguishingIndex can't possibly
 | 
						|
                    # be unset here, because we've already checked that argc is
 | 
						|
                    # large enough that we can examine this argument.
 | 
						|
                    testCode = instantiateJSToNativeConversionTemplate(
 | 
						|
                        getJSToNativeConversionTemplate(type, descriptor,
 | 
						|
                                                        failureCode="break;",
 | 
						|
                                                        isDefinitelyObject=True),
 | 
						|
                        {
 | 
						|
                            "declName" : "arg%d" % distinguishingIndex,
 | 
						|
                            "holderName" : ("arg%d" % distinguishingIndex) + "_holder",
 | 
						|
                            "val" : distinguishingArg
 | 
						|
                            })
 | 
						|
 | 
						|
                    # Indent by 4, since we need to indent further than our "do" statement
 | 
						|
                    caseBody.append(CGIndenter(testCode, 4));
 | 
						|
                    # If we got this far, we know we unwrapped to the right
 | 
						|
                    # interface, so just do the call.  Start conversion with
 | 
						|
                    # distinguishingIndex + 1, since we already converted
 | 
						|
                    # distinguishingIndex.
 | 
						|
                    caseBody.append(CGIndenter(
 | 
						|
                            getPerSignatureCall(sig, distinguishingIndex + 1), 4))
 | 
						|
                    caseBody.append(CGIndenter(CGGeneric("} while (0);")))
 | 
						|
 | 
						|
                caseBody.append(CGGeneric("}"))
 | 
						|
 | 
						|
            # XXXbz Now we're supposed to check for distinguishingArg being
 | 
						|
            # an array or a platform object that supports indexed
 | 
						|
            # properties... skip that last for now.  It's a bit of a pain.
 | 
						|
            pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject())" %
 | 
						|
                               (distinguishingArg, distinguishingArg),
 | 
						|
                               lambda s:
 | 
						|
                                   (s[1][distinguishingIndex].type.isArray() or
 | 
						|
                                    s[1][distinguishingIndex].type.isSequence() or
 | 
						|
                                    s[1][distinguishingIndex].type.isObject()))
 | 
						|
 | 
						|
            # Check for Date objects
 | 
						|
            # XXXbz Do we need to worry about security wrappers around the Date?
 | 
						|
            pickFirstSignature("%s.isObject() && JS_ObjectIsDate(cx, &%s.toObject())" %
 | 
						|
                               (distinguishingArg, distinguishingArg),
 | 
						|
                               lambda s: (s[1][distinguishingIndex].type.isDate() or
 | 
						|
                                          s[1][distinguishingIndex].type.isObject()))
 | 
						|
 | 
						|
            # Check for vanilla JS objects
 | 
						|
            # XXXbz Do we need to worry about security wrappers?
 | 
						|
            pickFirstSignature("%s.isObject() && !IsPlatformObject(cx, &%s.toObject())" %
 | 
						|
                               (distinguishingArg, distinguishingArg),
 | 
						|
                               lambda s: (s[1][distinguishingIndex].type.isCallback() or
 | 
						|
                                          s[1][distinguishingIndex].type.isCallbackInterface() or
 | 
						|
                                          s[1][distinguishingIndex].type.isDictionary() or
 | 
						|
                                          s[1][distinguishingIndex].type.isObject()))
 | 
						|
 | 
						|
            # The remaining cases are mutually exclusive.  The
 | 
						|
            # pickFirstSignature calls are what change caseBody
 | 
						|
            # Check for strings or enums
 | 
						|
            if pickFirstSignature(None,
 | 
						|
                                  lambda s: (s[1][distinguishingIndex].type.isString() or
 | 
						|
                                             s[1][distinguishingIndex].type.isEnum())):
 | 
						|
                pass
 | 
						|
            # Check for primitives
 | 
						|
            elif pickFirstSignature(None,
 | 
						|
                                    lambda s: s[1][distinguishingIndex].type.isPrimitive()):
 | 
						|
                pass
 | 
						|
            # Check for "any"
 | 
						|
            elif pickFirstSignature(None,
 | 
						|
                                    lambda s: s[1][distinguishingIndex].type.isAny()):
 | 
						|
                pass
 | 
						|
            else:
 | 
						|
                # Just throw; we have no idea what we're supposed to
 | 
						|
                # do with this.
 | 
						|
                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")))
 | 
						|
 | 
						|
        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)))
 | 
						|
        overloadCGThings.append(
 | 
						|
            CGGeneric('MOZ_NOT_REACHED("We have an always-returning default case");\n'
 | 
						|
                      'return false;'))
 | 
						|
        self.cgRoot = CGWrapper(CGIndenter(CGList(overloadCGThings, "\n")),
 | 
						|
                                pre="\n")
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return self.cgRoot.define()
 | 
						|
 | 
						|
class CGGetterCall(CGPerSignatureCall):
 | 
						|
    """
 | 
						|
    A class to generate a native object getter call for a particular IDL
 | 
						|
    getter.
 | 
						|
    """
 | 
						|
    def __init__(self, returnType, nativeMethodName, descriptor, attr):
 | 
						|
        CGPerSignatureCall.__init__(self, returnType, [], [],
 | 
						|
                                    nativeMethodName, False, descriptor,
 | 
						|
                                    attr, getter=True)
 | 
						|
 | 
						|
class FakeArgument():
 | 
						|
    """
 | 
						|
    A class that quacks like an IDLArgument.  This is used to make
 | 
						|
    setters look like method calls or for special operations.
 | 
						|
    """
 | 
						|
    def __init__(self, type, interfaceMember):
 | 
						|
        self.type = type
 | 
						|
        self.optional = False
 | 
						|
        self.variadic = False
 | 
						|
        self.defaultValue = None
 | 
						|
        self.treatNullAs = interfaceMember.treatNullAs
 | 
						|
        self.treatUndefinedAs = interfaceMember.treatUndefinedAs
 | 
						|
        self.enforceRange = False
 | 
						|
        self.clamp = False
 | 
						|
 | 
						|
class CGSetterCall(CGPerSignatureCall):
 | 
						|
    """
 | 
						|
    A class to generate a native object setter call for a particular IDL
 | 
						|
    setter.
 | 
						|
    """
 | 
						|
    def __init__(self, argType, nativeMethodName, descriptor, attr):
 | 
						|
        CGPerSignatureCall.__init__(self, None, [],
 | 
						|
                                    [FakeArgument(argType, attr)],
 | 
						|
                                    nativeMethodName, False, descriptor, attr,
 | 
						|
                                    setter=True)
 | 
						|
    def wrap_return_value(self):
 | 
						|
        # We have no return value
 | 
						|
        return "\nreturn true;"
 | 
						|
    def getArgc(self):
 | 
						|
        return "1"
 | 
						|
    def getArgvDecl(self):
 | 
						|
        # We just get our stuff from our last arg no matter what
 | 
						|
        return ""
 | 
						|
 | 
						|
class FakeCastableDescriptor():
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        self.castable = True
 | 
						|
        self.workers = descriptor.workers
 | 
						|
        self.nativeType = descriptor.nativeType
 | 
						|
        self.name = descriptor.name
 | 
						|
        self.hasXPConnectImpls = descriptor.hasXPConnectImpls
 | 
						|
 | 
						|
class CGAbstractBindingMethod(CGAbstractStaticMethod):
 | 
						|
    """
 | 
						|
    Common class to generate the JSNatives for all our methods, getters, and
 | 
						|
    setters.  This will generate the function declaration and unwrap the
 | 
						|
    |this| object.  Subclasses are expected to override the generate_code
 | 
						|
    function to do the rest of the work.  This function should return a
 | 
						|
    CGThing which is already properly indented.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, name, args, unwrapFailureCode=None):
 | 
						|
        CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
 | 
						|
 | 
						|
        if unwrapFailureCode is None:
 | 
						|
            self.unwrapFailureCode = ("return Throw<%s>(cx, rv);" %
 | 
						|
                                      toStringBool(not descriptor.workers))
 | 
						|
        else:
 | 
						|
            self.unwrapFailureCode = unwrapFailureCode
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        # Our descriptor might claim that we're not castable, simply because
 | 
						|
        # we're someone's consequential interface.  But for this-unwrapping, we
 | 
						|
        # know that we're the real deal.  So fake a descriptor here for
 | 
						|
        # consumption by FailureFatalCastableObjectUnwrapper.
 | 
						|
        unwrapThis = CGIndenter(CGGeneric(
 | 
						|
            str(CastableObjectUnwrapper(
 | 
						|
                        FakeCastableDescriptor(self.descriptor),
 | 
						|
                        "obj", "self", self.unwrapFailureCode))))
 | 
						|
        return CGList([ self.getThis(), unwrapThis,
 | 
						|
                        self.generate_code() ], "\n").define()
 | 
						|
 | 
						|
    def getThis(self):
 | 
						|
        return CGIndenter(
 | 
						|
            CGGeneric("js::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));\n"
 | 
						|
                      "if (!obj) {\n"
 | 
						|
                      "  return false;\n"
 | 
						|
                      "}\n"
 | 
						|
                      "\n"
 | 
						|
                      "%s* self;" % self.descriptor.nativeType))
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        assert(False) # Override me
 | 
						|
 | 
						|
def MakeNativeName(name):
 | 
						|
    return name[0].upper() + name[1:]
 | 
						|
 | 
						|
class CGGenericMethod(CGAbstractBindingMethod):
 | 
						|
    """
 | 
						|
    A class for generating the C++ code for an IDL method..
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
 | 
						|
                Argument('JS::Value*', 'vp')]
 | 
						|
        CGAbstractBindingMethod.__init__(self, descriptor, 'genericMethod', args)
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        return CGIndenter(CGGeneric(
 | 
						|
            "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
 | 
						|
            "JSJitMethodOp method = (JSJitMethodOp)info->op;\n"
 | 
						|
            "return method(cx, obj, self, argc, vp);"))
 | 
						|
 | 
						|
class CGSpecializedMethod(CGAbstractStaticMethod):
 | 
						|
    """
 | 
						|
    A class for generating the C++ code for a specialized method that the JIT
 | 
						|
    can call with lower overhead.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, method):
 | 
						|
        self.method = method
 | 
						|
        name = method.identifier.name
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
 | 
						|
                Argument('%s*' % descriptor.nativeType, 'self'),
 | 
						|
                Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')]
 | 
						|
        CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        name = self.method.identifier.name
 | 
						|
        nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
 | 
						|
        return CGMethodCall([], nativeName, self.method.isStatic(),
 | 
						|
                            self.descriptor, self.method).define()
 | 
						|
 | 
						|
class CGGenericGetter(CGAbstractBindingMethod):
 | 
						|
    """
 | 
						|
    A class for generating the C++ code for an IDL attribute getter.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, lenientThis=False):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
 | 
						|
                Argument('JS::Value*', 'vp')]
 | 
						|
        if lenientThis:
 | 
						|
            name = "genericLenientGetter"
 | 
						|
            unwrapFailureCode = (
 | 
						|
                "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
 | 
						|
                "JS_SET_RVAL(cx, vp, JS::UndefinedValue());\n"
 | 
						|
                "return true;")
 | 
						|
        else:
 | 
						|
            name = "genericGetter"
 | 
						|
            unwrapFailureCode = None
 | 
						|
        CGAbstractBindingMethod.__init__(self, descriptor, name, args,
 | 
						|
                                         unwrapFailureCode)
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        return CGIndenter(CGGeneric(
 | 
						|
            "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
 | 
						|
            "JSJitPropertyOp getter = info->op;\n"
 | 
						|
            "return getter(cx, obj, self, vp);"))
 | 
						|
 | 
						|
class CGSpecializedGetter(CGAbstractStaticMethod):
 | 
						|
    """
 | 
						|
    A class for generating the code for a specialized attribute getter
 | 
						|
    that the JIT can call with lower overhead.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, attr):
 | 
						|
        self.attr = attr
 | 
						|
        name = 'get_' + attr.identifier.name
 | 
						|
        args = [ Argument('JSContext*', 'cx'),
 | 
						|
                 Argument('JSHandleObject', 'obj'),
 | 
						|
                 Argument('%s*' % descriptor.nativeType, 'self'),
 | 
						|
                 Argument('JS::Value*', 'vp') ]
 | 
						|
        CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        name = self.attr.identifier.name
 | 
						|
        nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
 | 
						|
        # resultOutParam does not depend on whether resultAlreadyAddRefed is set
 | 
						|
        (_, resultOutParam) = getRetvalDeclarationForType(self.attr.type,
 | 
						|
                                                          self.descriptor,
 | 
						|
                                                          False)
 | 
						|
        infallible = ('infallible' in
 | 
						|
                      self.descriptor.getExtendedAttributes(self.attr,
 | 
						|
                                                            getter=True))
 | 
						|
        if resultOutParam or self.attr.type.nullable() or not infallible:
 | 
						|
            nativeName = "Get" + nativeName
 | 
						|
        return CGIndenter(CGGetterCall(self.attr.type, nativeName,
 | 
						|
                                       self.descriptor, self.attr)).define()
 | 
						|
 | 
						|
class CGGenericSetter(CGAbstractBindingMethod):
 | 
						|
    """
 | 
						|
    A class for generating the C++ code for an IDL attribute setter.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, lenientThis=False):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
 | 
						|
                Argument('JS::Value*', 'vp')]
 | 
						|
        if lenientThis:
 | 
						|
            name = "genericLenientSetter"
 | 
						|
            unwrapFailureCode = (
 | 
						|
                "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
 | 
						|
                "return true;")
 | 
						|
        else:
 | 
						|
            name = "genericSetter"
 | 
						|
            unwrapFailureCode = None
 | 
						|
        CGAbstractBindingMethod.__init__(self, descriptor, name, args,
 | 
						|
                                         unwrapFailureCode)
 | 
						|
 | 
						|
    def generate_code(self):
 | 
						|
        return CGIndenter(CGGeneric(
 | 
						|
                "JS::Value* argv = JS_ARGV(cx, vp);\n"
 | 
						|
                "JS::Value undef = JS::UndefinedValue();\n"
 | 
						|
                "if (argc == 0) {\n"
 | 
						|
                "  argv = &undef;\n"
 | 
						|
                "}\n"
 | 
						|
                "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
 | 
						|
                "JSJitPropertyOp setter = info->op;\n"
 | 
						|
                "if (!setter(cx, obj, self, argv)) {\n"
 | 
						|
                "  return false;\n"
 | 
						|
                "}\n"
 | 
						|
                "*vp = JSVAL_VOID;\n"
 | 
						|
                "return true;"))
 | 
						|
 | 
						|
class CGSpecializedSetter(CGAbstractStaticMethod):
 | 
						|
    """
 | 
						|
    A class for generating the code for a specialized attribute setter
 | 
						|
    that the JIT can call with lower overhead.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, attr):
 | 
						|
        self.attr = attr
 | 
						|
        name = 'set_' + attr.identifier.name
 | 
						|
        args = [ Argument('JSContext*', 'cx'),
 | 
						|
                 Argument('JSHandleObject', 'obj'),
 | 
						|
                 Argument('%s*' % descriptor.nativeType, 'self'),
 | 
						|
                 Argument('JS::Value*', 'argv')]
 | 
						|
        CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        name = self.attr.identifier.name
 | 
						|
        nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
 | 
						|
        return CGIndenter(CGSetterCall(self.attr.type, nativeName,
 | 
						|
                                       self.descriptor, self.attr)).define()
 | 
						|
 | 
						|
def memberIsCreator(member):
 | 
						|
    return member.getExtendedAttribute("Creator") is not None
 | 
						|
 | 
						|
class CGMemberJITInfo(CGThing):
 | 
						|
    """
 | 
						|
    A class for generating the JITInfo for a property that points to
 | 
						|
    our specialized getter and setter.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, member):
 | 
						|
        self.member = member
 | 
						|
        self.descriptor = descriptor
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        return ""
 | 
						|
 | 
						|
    def defineJitInfo(self, infoName, opName, infallible):
 | 
						|
        protoID = "prototypes::id::%s" % self.descriptor.name
 | 
						|
        depth = "PrototypeTraits<%s>::Depth" % protoID
 | 
						|
        failstr = "true" if infallible else "false"
 | 
						|
        return ("\n"
 | 
						|
                "const JSJitInfo %s = {\n"
 | 
						|
                "  %s,\n"
 | 
						|
                "  %s,\n"
 | 
						|
                "  %s,\n"
 | 
						|
                "  %s,  /* isInfallible. False in setters. */\n"
 | 
						|
                "  false  /* isConstant. Only relevant for getters. */\n"
 | 
						|
                "};\n" % (infoName, opName, protoID, depth, failstr))
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        if self.member.isAttr():
 | 
						|
            getterinfo = ("%s_getterinfo" % self.member.identifier.name)
 | 
						|
            getter = ("(JSJitPropertyOp)get_%s" % self.member.identifier.name)
 | 
						|
            getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
 | 
						|
            getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
 | 
						|
            result = self.defineJitInfo(getterinfo, getter, getterinfal)
 | 
						|
            if not self.member.readonly:
 | 
						|
                setterinfo = ("%s_setterinfo" % self.member.identifier.name)
 | 
						|
                setter = ("(JSJitPropertyOp)set_%s" % self.member.identifier.name)
 | 
						|
                # Setters are always fallible, since they have to do a typed unwrap.
 | 
						|
                result += self.defineJitInfo(setterinfo, setter, False)
 | 
						|
            return result
 | 
						|
        if self.member.isMethod():
 | 
						|
            methodinfo = ("%s_methodinfo" % self.member.identifier.name)
 | 
						|
            # Actually a JSJitMethodOp, but JSJitPropertyOp by struct definition.
 | 
						|
            method = ("(JSJitPropertyOp)%s" % self.member.identifier.name)
 | 
						|
 | 
						|
            # Methods are infallible if they are infallible, have no arguments
 | 
						|
            # to unwrap, and have a return type that's infallible to wrap up for
 | 
						|
            # return.
 | 
						|
            methodInfal = False
 | 
						|
            sigs = self.member.signatures()
 | 
						|
            if len(sigs) == 1:
 | 
						|
                # Don't handle overloading. If there's more than one signature,
 | 
						|
                # one of them must take arguments.
 | 
						|
                sig = sigs[0]
 | 
						|
                if len(sig[1]) == 0 and infallibleForMember(self.member, sig[0], self.descriptor):
 | 
						|
                    # No arguments and infallible return boxing
 | 
						|
                    methodInfal = True
 | 
						|
 | 
						|
            result = self.defineJitInfo(methodinfo, method, methodInfal)
 | 
						|
            return result
 | 
						|
        raise TypeError("Illegal member type to CGPropertyJITInfo")
 | 
						|
 | 
						|
def getEnumValueName(value):
 | 
						|
    # Some enum values can be empty strings.  Others might have weird
 | 
						|
    # characters in them.  Deal with the former by returning "_empty",
 | 
						|
    # deal with possible name collisions from that by throwing if the
 | 
						|
    # enum value is actually "_empty", and throw on any value
 | 
						|
    # containing chars other than [a-z] or '-' for now. Replace '-' with '_'.
 | 
						|
    value = value.replace('-', '_')
 | 
						|
    if value == "_empty":
 | 
						|
        raise SyntaxError('"_empty" is not an IDL enum value we support yet')
 | 
						|
    if value == "":
 | 
						|
        return "_empty"
 | 
						|
    if not re.match("^[a-z_]+$", value):
 | 
						|
        raise SyntaxError('Enum value "' + value + '" contains characters '
 | 
						|
                          'outside [a-z_]')
 | 
						|
    return MakeNativeName(value)
 | 
						|
 | 
						|
class CGEnum(CGThing):
 | 
						|
    def __init__(self, enum):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.enum = enum
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        return """
 | 
						|
  enum valuelist {
 | 
						|
    %s
 | 
						|
  };
 | 
						|
 | 
						|
  extern const EnumEntry strings[%d];
 | 
						|
""" % (",\n    ".join(map(getEnumValueName, self.enum.values())),
 | 
						|
       len(self.enum.values()) + 1)
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return """
 | 
						|
  const EnumEntry strings[%d] = {
 | 
						|
    %s,
 | 
						|
    { NULL, 0 }
 | 
						|
  };
 | 
						|
""" % (len(self.enum.values()) + 1,
 | 
						|
       ",\n    ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
 | 
						|
 | 
						|
def getUnionAccessorSignatureType(type, descriptorProvider):
 | 
						|
    """
 | 
						|
    Returns the types that are used in the getter and setter signatures for
 | 
						|
    union types
 | 
						|
    """
 | 
						|
    if type.isArray():
 | 
						|
        raise TypeError("Can't handle array arguments yet")
 | 
						|
 | 
						|
    if type.isSequence():
 | 
						|
        nullable = type.nullable();
 | 
						|
        if nullable:
 | 
						|
            type = type.inner.inner
 | 
						|
        else:
 | 
						|
            type = type.inner
 | 
						|
        (elementTemplate, elementDeclType,
 | 
						|
         elementHolderType, dealWithOptional) = getJSToNativeConversionTemplate(
 | 
						|
            type, descriptorProvider, isSequenceMember=True)
 | 
						|
        typeName = CGWrapper(elementDeclType, pre="Sequence< ", post=" >&")
 | 
						|
        if nullable:
 | 
						|
            typeName = CGWrapper(typeName, pre="Nullable< ", post=" >&")
 | 
						|
 | 
						|
        return typeName
 | 
						|
 | 
						|
    if type.isUnion():
 | 
						|
        typeName = CGGeneric(type.name)
 | 
						|
        if type.nullable():
 | 
						|
            typeName = CGWrapper(typeName, pre="Nullable< ", post=" >&")
 | 
						|
 | 
						|
        return typeName
 | 
						|
 | 
						|
    if type.isGeckoInterface():
 | 
						|
        descriptor = descriptorProvider.getDescriptor(
 | 
						|
            type.unroll().inner.identifier.name)
 | 
						|
        typeName = CGGeneric(descriptor.nativeType)
 | 
						|
        # Allow null pointers for nullable types and old-binding classes
 | 
						|
        if type.nullable() or type.unroll().inner.isExternal():
 | 
						|
            typeName = CGWrapper(typeName, post="*")
 | 
						|
        else:
 | 
						|
            typeName = CGWrapper(typeName, post="&")
 | 
						|
        return typeName
 | 
						|
 | 
						|
    if type.isSpiderMonkeyInterface():
 | 
						|
        typeName = CGGeneric(type.name)
 | 
						|
        if type.nullable():
 | 
						|
            typeName = CGWrapper(typeName, post="*")
 | 
						|
        else:
 | 
						|
            typeName = CGWrapper(typeName, post="&")
 | 
						|
        return typeName
 | 
						|
 | 
						|
    if type.isString():
 | 
						|
        return CGGeneric("const nsAString&")
 | 
						|
 | 
						|
    if type.isEnum():
 | 
						|
        if type.nullable():
 | 
						|
            raise TypeError("We don't support nullable enumerated arguments or "
 | 
						|
                            "union members yet")
 | 
						|
        return CGGeneric(type.inner.identifier.name)
 | 
						|
 | 
						|
    if type.isCallback():
 | 
						|
        return CGGeneric("JSObject*")
 | 
						|
 | 
						|
    if type.isAny():
 | 
						|
        return CGGeneric("JS::Value")
 | 
						|
 | 
						|
    if type.isObject():
 | 
						|
        typeName = CGGeneric("JSObject")
 | 
						|
        if type.nullable():
 | 
						|
            typeName = CGWrapper(typeName, post="*")
 | 
						|
        else:
 | 
						|
            typeName = CGWrapper(typeName, post="&")
 | 
						|
        return typeName
 | 
						|
 | 
						|
    if not type.isPrimitive():
 | 
						|
        raise TypeError("Need native type for argument type '%s'" % str(type))
 | 
						|
 | 
						|
    typeName = CGGeneric(builtinNames[type.tag()])
 | 
						|
    if type.nullable():
 | 
						|
        typeName = CGWrapper(typeName, pre="Nullable< ", post=" >&")
 | 
						|
    return typeName
 | 
						|
 | 
						|
def getUnionTypeTemplateVars(type, descriptorProvider):
 | 
						|
    # For dictionaries and sequences we need to pass None as the failureCode
 | 
						|
    # for getJSToNativeConversionTemplate.
 | 
						|
    # Also, for dictionaries we would need to handle conversion of
 | 
						|
    # null/undefined to the dictionary correctly.
 | 
						|
    if type.isDictionary() or type.isSequence():
 | 
						|
        raise TypeError("Can't handle dictionaries or sequences in unions")
 | 
						|
 | 
						|
    if type.isGeckoInterface():
 | 
						|
        name = type.inner.identifier.name
 | 
						|
    elif type.isEnum():
 | 
						|
        name = type.inner.identifier.name
 | 
						|
    elif type.isArray() or type.isSequence():
 | 
						|
        name = str(type)
 | 
						|
    else:
 | 
						|
        name = type.name
 | 
						|
 | 
						|
    tryNextCode = """tryNext = true;
 | 
						|
return true;"""
 | 
						|
    if type.isGeckoInterface():
 | 
						|
         tryNextCode = ("""if (mUnion.mType != mUnion.eUninitialized) {
 | 
						|
  mUnion.Destroy%s();
 | 
						|
}""" % name) + tryNextCode
 | 
						|
    (template, declType, holderType,
 | 
						|
     dealWithOptional) = getJSToNativeConversionTemplate(
 | 
						|
        type, descriptorProvider, failureCode=tryNextCode,
 | 
						|
        isDefinitelyObject=True)
 | 
						|
 | 
						|
    # This is ugly, but UnionMember needs to call a constructor with no
 | 
						|
    # arguments so the type can't be const.
 | 
						|
    structType = declType.define()
 | 
						|
    if structType.startswith("const "):
 | 
						|
        structType = structType[6:]
 | 
						|
    externalType = getUnionAccessorSignatureType(type, descriptorProvider).define()
 | 
						|
 | 
						|
    if type.isObject():
 | 
						|
        setter = CGGeneric("void SetToObject(JSObject* obj)\n"
 | 
						|
                           "{\n"
 | 
						|
                           "  mUnion.mValue.mObject.SetValue() = obj;\n"
 | 
						|
                           "  mUnion.mType = mUnion.eObject;\n"
 | 
						|
                           "}")
 | 
						|
    else:
 | 
						|
        jsConversion = string.Template(template).substitute(
 | 
						|
            {
 | 
						|
                "val": "value",
 | 
						|
                "valPtr": "pvalue",
 | 
						|
                "declName": "SetAs" + name + "()",
 | 
						|
                "holderName": "m" + name + "Holder"
 | 
						|
                }
 | 
						|
            )
 | 
						|
        jsConversion = CGWrapper(CGGeneric(jsConversion),
 | 
						|
                                 post="\n"
 | 
						|
                                      "return true;")
 | 
						|
        setter = CGWrapper(CGIndenter(jsConversion),
 | 
						|
                           pre="bool TrySetTo" + name + "(JSContext* cx, const JS::Value& value, JS::Value* pvalue, bool& tryNext)\n"
 | 
						|
                               "{\n"
 | 
						|
                               "  tryNext = false;\n",
 | 
						|
                           post="\n"
 | 
						|
                                "}")
 | 
						|
 | 
						|
    return {
 | 
						|
                "name": name,
 | 
						|
                "structType": structType,
 | 
						|
                "externalType": externalType,
 | 
						|
                "setter": CGIndenter(setter).define(),
 | 
						|
                "holderType": holderType.define() if holderType else None
 | 
						|
                }
 | 
						|
 | 
						|
def mapTemplate(template, templateVarArray):
 | 
						|
    return map(lambda v: string.Template(template).substitute(v),
 | 
						|
               templateVarArray)
 | 
						|
 | 
						|
class CGUnionStruct(CGThing):
 | 
						|
    def __init__(self, type, descriptorProvider):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.type = type.unroll()
 | 
						|
        self.descriptorProvider = descriptorProvider
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
 | 
						|
                           self.type.flatMemberTypes)
 | 
						|
 | 
						|
        callDestructors = []
 | 
						|
        enumValues = []
 | 
						|
        methods = []
 | 
						|
        if self.type.hasNullableType:
 | 
						|
            callDestructors.append("      case eNull:\n"
 | 
						|
                                   "        break;")
 | 
						|
            enumValues.append("eNull")
 | 
						|
            methods.append("""  bool IsNull() const
 | 
						|
  {
 | 
						|
    return mType == eNull;
 | 
						|
  }""")
 | 
						|
 | 
						|
        destructorTemplate = """  void Destroy${name}()
 | 
						|
  {
 | 
						|
    MOZ_ASSERT(Is${name}(), "Wrong type!");
 | 
						|
    mValue.m${name}.Destroy();
 | 
						|
    mType = eUninitialized;
 | 
						|
  }"""
 | 
						|
        destructors = mapTemplate(destructorTemplate, templateVars)
 | 
						|
        callDestructors.extend(mapTemplate("      case e${name}:\n"
 | 
						|
                                           "         Destroy${name}();\n"
 | 
						|
                                           "         break;", templateVars))
 | 
						|
        enumValues.extend(mapTemplate("e${name}", templateVars))
 | 
						|
        methodTemplate = """  bool Is${name}() const
 | 
						|
  {
 | 
						|
    return mType == e${name};
 | 
						|
  }
 | 
						|
  ${externalType} GetAs${name}() const
 | 
						|
  {
 | 
						|
    MOZ_ASSERT(Is${name}(), "Wrong type!");
 | 
						|
    // The cast to ${externalType} is needed to work around a bug in Apple's
 | 
						|
    // clang compiler, for some reason it doesn't call |S::operator T&| when
 | 
						|
    // casting S<T> to T& and T is forward declared.
 | 
						|
    return (${externalType})mValue.m${name}.Value();
 | 
						|
  }
 | 
						|
  ${structType}& SetAs${name}()
 | 
						|
  {
 | 
						|
    mType = e${name};
 | 
						|
    return mValue.m${name}.SetValue();
 | 
						|
  }"""
 | 
						|
        methods.extend(mapTemplate(methodTemplate, templateVars))
 | 
						|
        values = mapTemplate("UnionMember<${structType} > m${name};", templateVars)
 | 
						|
        return string.Template("""
 | 
						|
class ${structName} {
 | 
						|
public:
 | 
						|
  ${structName}() : mType(eUninitialized)
 | 
						|
  {
 | 
						|
  }
 | 
						|
  ~${structName}()
 | 
						|
  {
 | 
						|
    switch (mType) {
 | 
						|
${callDestructors}
 | 
						|
      case eUninitialized:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
${methods}
 | 
						|
 | 
						|
private:
 | 
						|
  friend class ${structName}Argument;
 | 
						|
 | 
						|
${destructors}
 | 
						|
 | 
						|
  enum Type {
 | 
						|
    eUninitialized,
 | 
						|
    ${enumValues}
 | 
						|
  };
 | 
						|
  union Value {
 | 
						|
    ${values}
 | 
						|
  };
 | 
						|
 | 
						|
  Type mType;
 | 
						|
  Value mValue;
 | 
						|
};
 | 
						|
 | 
						|
""").substitute(
 | 
						|
    {
 | 
						|
       "structName": self.type.__str__(),
 | 
						|
       "callDestructors": "\n".join(callDestructors),
 | 
						|
       "destructors": "\n".join(destructors),
 | 
						|
       "methods": "\n\n".join(methods),
 | 
						|
       "enumValues": ",\n    ".join(enumValues),
 | 
						|
       "values": "\n    ".join(values),
 | 
						|
       })
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return """
 | 
						|
"""
 | 
						|
 | 
						|
class CGUnionConversionStruct(CGThing):
 | 
						|
    def __init__(self, type, descriptorProvider):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.type = type.unroll()
 | 
						|
        self.descriptorProvider = descriptorProvider
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        setters = []
 | 
						|
 | 
						|
        if self.type.hasNullableType:
 | 
						|
            setters.append("""  bool SetNull()
 | 
						|
  {
 | 
						|
    mUnion.mType = mUnion.eNull;
 | 
						|
    return true;
 | 
						|
  }""")
 | 
						|
 | 
						|
        templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
 | 
						|
                           self.type.flatMemberTypes)
 | 
						|
        structName = self.type.__str__()
 | 
						|
 | 
						|
        setters.extend(mapTemplate("${setter}", templateVars))
 | 
						|
        private = "\n".join(mapTemplate("""  ${structType}& SetAs${name}()
 | 
						|
  {
 | 
						|
    mUnion.mType = mUnion.e${name};
 | 
						|
    return mUnion.mValue.m${name}.SetValue();
 | 
						|
  }""", templateVars))
 | 
						|
        private += "\n\n"
 | 
						|
        holders = filter(lambda v: v["holderType"] is not None, templateVars)
 | 
						|
        if len(holders) > 0:
 | 
						|
            private += "\n".join(mapTemplate("  ${holderType} m${name}Holder;", holders))
 | 
						|
            private += "\n\n"
 | 
						|
        private += "  " + structName + "& mUnion;"
 | 
						|
        return string.Template("""
 | 
						|
class ${structName}Argument {
 | 
						|
public:
 | 
						|
  ${structName}Argument(const ${structName}& aUnion) : mUnion(const_cast<${structName}&>(aUnion))
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
${setters}
 | 
						|
 | 
						|
private:
 | 
						|
${private}
 | 
						|
};
 | 
						|
""").substitute({"structName": structName,
 | 
						|
       "setters": "\n\n".join(setters),
 | 
						|
       "private": private
 | 
						|
       })
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        return """
 | 
						|
"""
 | 
						|
 | 
						|
class ClassItem:
 | 
						|
    """ Use with CGClass """
 | 
						|
    def __init__(self, name, visibility):
 | 
						|
        self.name = name
 | 
						|
        self.visibility = visibility
 | 
						|
    def declare(self, cgClass):
 | 
						|
        assert False
 | 
						|
    def define(self, cgClass):
 | 
						|
        assert False
 | 
						|
 | 
						|
class ClassBase(ClassItem):
 | 
						|
    def __init__(self, name, visibility='public'):
 | 
						|
        ClassItem.__init__(self, name, visibility)
 | 
						|
    def declare(self, cgClass):
 | 
						|
        return '%s %s' % (self.visibility, self.name)
 | 
						|
    def define(self, cgClass):
 | 
						|
        # Only in the header
 | 
						|
        return ''
 | 
						|
 | 
						|
class ClassMethod(ClassItem):
 | 
						|
    def __init__(self, name, returnType, args, inline=False, static=False,
 | 
						|
                 virtual=False, const=False, bodyInHeader=False,
 | 
						|
                 templateArgs=None, visibility='public', body=None):
 | 
						|
        self.returnType = returnType
 | 
						|
        self.args = args
 | 
						|
        self.inline = inline or bodyInHeader
 | 
						|
        self.static = static
 | 
						|
        self.virtual = virtual
 | 
						|
        self.const = const
 | 
						|
        self.bodyInHeader = bodyInHeader
 | 
						|
        self.templateArgs = templateArgs
 | 
						|
        self.body = body
 | 
						|
        ClassItem.__init__(self, name, visibility)
 | 
						|
 | 
						|
    def getDecorators(self, declaring):
 | 
						|
        decorators = []
 | 
						|
        if self.inline:
 | 
						|
            decorators.append('inline')
 | 
						|
        if declaring:
 | 
						|
            if self.static:
 | 
						|
                decorators.append('static')
 | 
						|
            if self.virtual:
 | 
						|
                decorators.append('virtual')
 | 
						|
        if decorators:
 | 
						|
            return ' '.join(decorators) + ' '
 | 
						|
        return ''
 | 
						|
 | 
						|
    def getBody(self):
 | 
						|
        # Override me or pass a string to constructor
 | 
						|
        assert self.body is not None
 | 
						|
        return self.body
 | 
						|
 | 
						|
    def declare(self, cgClass):
 | 
						|
        templateClause = 'template <%s>\n' % ', '.join(self.templateArgs) \
 | 
						|
                         if self.bodyInHeader and self.templateArgs else ''
 | 
						|
        args = ', '.join([str(a) for a in self.args])
 | 
						|
        if self.bodyInHeader:
 | 
						|
            body = CGIndenter(CGGeneric(self.getBody())).define()
 | 
						|
            body = '\n{\n' + body + '\n}'
 | 
						|
        else:
 | 
						|
           body = ';'
 | 
						|
 | 
						|
        return string.Template("""${templateClause}${decorators}${returnType}
 | 
						|
${name}(${args})${const}${body}
 | 
						|
""").substitute({ 'templateClause': templateClause,
 | 
						|
                  'decorators': self.getDecorators(True),
 | 
						|
                  'returnType': self.returnType,
 | 
						|
                  'name': self.name,
 | 
						|
                  'const': ' const' if self.const else '',
 | 
						|
                  'args': args,
 | 
						|
                  'body': body })
 | 
						|
 | 
						|
    def define(self, cgClass):
 | 
						|
        if self.bodyInHeader:
 | 
						|
            return ''
 | 
						|
 | 
						|
        templateArgs = cgClass.templateArgs
 | 
						|
        if templateArgs:
 | 
						|
            if cgClass.templateSpecialization:
 | 
						|
                templateArgs = \
 | 
						|
                    templateArgs[len(cgClass.templateSpecialization):]
 | 
						|
 | 
						|
        if templateArgs:
 | 
						|
            templateClause = \
 | 
						|
                'template <%s>\n' % ', '.join([str(a) for a in templateArgs])
 | 
						|
        else:
 | 
						|
            templateClause = ''
 | 
						|
 | 
						|
        args = ', '.join([str(a) for a in self.args])
 | 
						|
 | 
						|
        body = CGIndenter(CGGeneric(self.getBody())).define()
 | 
						|
 | 
						|
        return string.Template("""${templateClause}${decorators}${returnType}
 | 
						|
${className}::${name}(${args})${const}
 | 
						|
{
 | 
						|
${body}
 | 
						|
}\n
 | 
						|
""").substitute({ 'templateClause': templateClause,
 | 
						|
                  'decorators': self.getDecorators(False),
 | 
						|
                  'returnType': self.returnType,
 | 
						|
                  'className': cgClass.getNameString(),
 | 
						|
                  'name': self.name,
 | 
						|
                  'args': args,
 | 
						|
                  'const': ' const' if self.const else '',
 | 
						|
                  'body': body })
 | 
						|
 | 
						|
class ClassConstructor(ClassItem):
 | 
						|
    """
 | 
						|
    Used for adding a constructor to a CGClass.
 | 
						|
    
 | 
						|
    args is a list of Argument objects that are the arguments taken by the
 | 
						|
    constructor.
 | 
						|
    
 | 
						|
    inline should be True if the constructor should be marked inline.
 | 
						|
 | 
						|
    bodyInHeader should be True if the body should be placed in the class
 | 
						|
    declaration in the header.
 | 
						|
 | 
						|
    visibility determines the visibility of the constructor (public,
 | 
						|
    protected, private), defaults to private.
 | 
						|
 | 
						|
    baseConstructors is a list of strings containing calls to base constructors,
 | 
						|
    defaults to None.
 | 
						|
 | 
						|
    body contains a string with the code for the constructor, defaults to None.
 | 
						|
    """
 | 
						|
    def __init__(self, args, inline=False, bodyInHeader=False,
 | 
						|
                 visibility="private", baseConstructors=None, body=None):
 | 
						|
        self.args = args
 | 
						|
        self.inline = inline or bodyInHeader
 | 
						|
        self.bodyInHeader = bodyInHeader
 | 
						|
        self.baseConstructors = baseConstructors
 | 
						|
        self.body = body
 | 
						|
        ClassItem.__init__(self, None, visibility)
 | 
						|
 | 
						|
    def getDecorators(self, declaring):
 | 
						|
        decorators = []
 | 
						|
        if self.inline and declaring:
 | 
						|
            decorators.append('inline')
 | 
						|
        if decorators:
 | 
						|
            return ' '.join(decorators) + ' '
 | 
						|
        return ''
 | 
						|
 | 
						|
    def getInitializationList(self, cgClass):
 | 
						|
        items = [str(c) for c in self.baseConstructors]
 | 
						|
        for m in cgClass.members:
 | 
						|
            if not m.static:
 | 
						|
                initialize = m.getBody()
 | 
						|
                if initialize:
 | 
						|
                    items.append(m.name + "(" + initialize + ")")
 | 
						|
            
 | 
						|
        if len(items) > 0:
 | 
						|
            return '\n  : ' + ',\n    '.join(items)
 | 
						|
        return ''
 | 
						|
 | 
						|
    def getBody(self):
 | 
						|
        assert self.body is not None
 | 
						|
        return self.body
 | 
						|
 | 
						|
    def declare(self, cgClass):
 | 
						|
        args = ', '.join([str(a) for a in self.args])
 | 
						|
        if self.bodyInHeader:
 | 
						|
            body = '  ' + self.getBody();
 | 
						|
            body = stripTrailingWhitespace(body.replace('\n', '\n  '))
 | 
						|
            if len(body) > 0:
 | 
						|
                body += '\n'
 | 
						|
            body = self.getInitializationList(cgClass) + '\n{\n' + body + '}'
 | 
						|
        else:
 | 
						|
            body = ';'
 | 
						|
 | 
						|
        return string.Template("""${decorators}${className}(${args})${body}
 | 
						|
""").substitute({ 'decorators': self.getDecorators(True),
 | 
						|
                  'className': cgClass.getNameString(),
 | 
						|
                  'args': args,
 | 
						|
                  'body': body })
 | 
						|
 | 
						|
    def define(self, cgClass):
 | 
						|
        if self.bodyInHeader:
 | 
						|
            return ''
 | 
						|
 | 
						|
        args = ', '.join([str(a) for a in self.args])
 | 
						|
 | 
						|
        body = '  ' + self.getBody()
 | 
						|
        body = '\n' + stripTrailingWhitespace(body.replace('\n', '\n  '))
 | 
						|
        if len(body) > 0:
 | 
						|
            body += '\n'
 | 
						|
 | 
						|
        return string.Template("""${decorators}
 | 
						|
${className}::${className}(${args})${initializationList}
 | 
						|
{${body}}\n
 | 
						|
""").substitute({ 'decorators': self.getDecorators(False),
 | 
						|
                  'className': cgClass.getNameString(),
 | 
						|
                  'args': args,
 | 
						|
                  'initializationList': self.getInitializationList(cgClass),
 | 
						|
                  'body': body })
 | 
						|
 | 
						|
class ClassMember(ClassItem):
 | 
						|
    def __init__(self, name, type, visibility="private", static=False,
 | 
						|
                 body=None):
 | 
						|
        self.type = type;
 | 
						|
        self.static = static
 | 
						|
        self.body = body
 | 
						|
        ClassItem.__init__(self, name, visibility)
 | 
						|
 | 
						|
    def declare(self, cgClass):
 | 
						|
        return '%s%s %s;\n' % ('static ' if self.static else '', self.type,
 | 
						|
                               self.name)
 | 
						|
 | 
						|
    def define(self, cgClass):
 | 
						|
        if not self.static:
 | 
						|
            return ''
 | 
						|
        if self.body:
 | 
						|
            body = " = " + self.body
 | 
						|
        else:
 | 
						|
            body = ""
 | 
						|
        return '%s %s::%s%s;\n' % (self.type, cgClass.getNameString(),
 | 
						|
                                      self.name, body)
 | 
						|
 | 
						|
class ClassTypedef(ClassItem):
 | 
						|
    def __init__(self, name, type, visibility="public"):
 | 
						|
        self.type = type
 | 
						|
        ClassItem.__init__(self, name, visibility)
 | 
						|
 | 
						|
    def declare(self, cgClass):
 | 
						|
        return 'typedef %s %s;\n' % (self.type, self.name)
 | 
						|
 | 
						|
    def define(self, cgClass):
 | 
						|
        # Only goes in the header
 | 
						|
        return ''
 | 
						|
 | 
						|
class ClassEnum(ClassItem):
 | 
						|
    def __init__(self, name, entries, values=None, visibility="public"):
 | 
						|
        self.entries = entries
 | 
						|
        self.values = values
 | 
						|
        ClassItem.__init__(self, name, visibility)
 | 
						|
 | 
						|
    def declare(self, cgClass):
 | 
						|
        entries = []
 | 
						|
        for i in range(0, len(self.entries)):
 | 
						|
            if i >= len(self.values):
 | 
						|
                entry = '%s' % self.entries[i]
 | 
						|
            else:
 | 
						|
                entry = '%s = %s' % (self.entries[i], self.values[i])
 | 
						|
            entries.append(entry)
 | 
						|
        name = '' if not self.name else ' ' + self.name
 | 
						|
        return 'enum%s\n{\n  %s\n};\n' % (name, ',\n  '.join(entries))
 | 
						|
 | 
						|
    def define(self, cgClass):
 | 
						|
        # Only goes in the header
 | 
						|
        return ''
 | 
						|
 | 
						|
class CGClass(CGThing):
 | 
						|
    def __init__(self, name, bases=[], members=[], constructors=[], methods=[],
 | 
						|
                 typedefs = [], enums=[], templateArgs=[],
 | 
						|
                 templateSpecialization=[], isStruct=False, indent=''):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.name = name
 | 
						|
        self.bases = bases
 | 
						|
        self.members = members
 | 
						|
        self.constructors = constructors
 | 
						|
        self.methods = methods
 | 
						|
        self.typedefs = typedefs
 | 
						|
        self.enums = enums
 | 
						|
        self.templateArgs = templateArgs
 | 
						|
        self.templateSpecialization = templateSpecialization
 | 
						|
        self.isStruct = isStruct
 | 
						|
        self.indent = indent
 | 
						|
        self.defaultVisibility ='public' if isStruct else 'private'
 | 
						|
 | 
						|
    def getNameString(self):
 | 
						|
        className = self.name
 | 
						|
        if self.templateSpecialization:
 | 
						|
            className = className + \
 | 
						|
                '<%s>' % ', '.join([str(a) for a
 | 
						|
                                    in self.templateSpecialization])
 | 
						|
        return className
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        result = ''
 | 
						|
        if self.templateArgs:
 | 
						|
            templateArgs = [str(a) for a in self.templateArgs]
 | 
						|
            templateArgs = templateArgs[len(self.templateSpecialization):]
 | 
						|
            result = result + self.indent + 'template <%s>\n' \
 | 
						|
                     % ','.join([str(a) for a in templateArgs])
 | 
						|
 | 
						|
        type = 'struct' if self.isStruct else 'class'
 | 
						|
 | 
						|
        if self.templateSpecialization:
 | 
						|
            specialization = \
 | 
						|
                '<%s>' % ', '.join([str(a) for a in self.templateSpecialization])
 | 
						|
        else:
 | 
						|
            specialization = ''
 | 
						|
 | 
						|
        result = result + '%s%s %s%s' \
 | 
						|
                 % (self.indent, type, self.name, specialization)
 | 
						|
 | 
						|
        if self.bases:
 | 
						|
            result = result + ' : %s' % ', '.join([d.declare(self) for d in self.bases])
 | 
						|
 | 
						|
        result = result + '\n%s{\n' % self.indent
 | 
						|
 | 
						|
        def declareMembers(cgClass, memberList, defaultVisibility, itemCount,
 | 
						|
                           separator=''):
 | 
						|
            members = { 'private': [], 'protected': [], 'public': [] }
 | 
						|
 | 
						|
            for member in memberList:
 | 
						|
                members[member.visibility].append(member)
 | 
						|
 | 
						|
 | 
						|
            if defaultVisibility == 'public':
 | 
						|
                order = [ 'public', 'protected', 'private' ]
 | 
						|
            else:
 | 
						|
                order = [ 'private', 'protected', 'public' ]
 | 
						|
 | 
						|
            result = ''
 | 
						|
 | 
						|
            lastVisibility = defaultVisibility
 | 
						|
            for visibility in order:
 | 
						|
                list = members[visibility]
 | 
						|
                if list:
 | 
						|
                    if visibility != lastVisibility:
 | 
						|
                        if itemCount:
 | 
						|
                            result = result + '\n'
 | 
						|
                        result = result + visibility + ':\n'
 | 
						|
                        itemCount = 0
 | 
						|
                    for member in list:
 | 
						|
                        if itemCount != 0:
 | 
						|
                            result = result + separator
 | 
						|
                        declaration = member.declare(cgClass)
 | 
						|
                        declaration = CGIndenter(CGGeneric(declaration)).define()
 | 
						|
                        result = result + declaration
 | 
						|
                        itemCount = itemCount + 1
 | 
						|
                    lastVisibility = visibility
 | 
						|
            return (result, lastVisibility, itemCount)
 | 
						|
 | 
						|
        order = [(self.enums, ''), (self.typedefs, ''), (self.members, ''),
 | 
						|
                 (self.constructors, '\n'), (self.methods, '\n')]
 | 
						|
 | 
						|
        lastVisibility = self.defaultVisibility
 | 
						|
        itemCount = 0
 | 
						|
        for (memberList, separator) in order:
 | 
						|
            (memberString, lastVisibility, itemCount) = \
 | 
						|
                declareMembers(self, memberList, lastVisibility, itemCount,
 | 
						|
                               separator)
 | 
						|
            if self.indent:
 | 
						|
                memberString = CGIndenter(CGGeneric(memberString),
 | 
						|
                                          len(self.indent)).define()
 | 
						|
            result = result + memberString
 | 
						|
 | 
						|
        result = result + self.indent + '};\n'
 | 
						|
        return result
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        def defineMembers(cgClass, memberList, itemCount, separator=''):
 | 
						|
            result = ''
 | 
						|
            for member in memberList:
 | 
						|
                if itemCount != 0:
 | 
						|
                    result = result + separator
 | 
						|
                result = result + member.define(cgClass)
 | 
						|
                itemCount = itemCount + 1
 | 
						|
            return (result, itemCount)
 | 
						|
 | 
						|
        order = [(self.members, '\n'), (self.constructors, '\n'),
 | 
						|
                 (self.methods, '\n')]
 | 
						|
 | 
						|
        result = ''
 | 
						|
        itemCount = 0
 | 
						|
        for (memberList, separator) in order:
 | 
						|
            (memberString, itemCount) = defineMembers(self, memberList,
 | 
						|
                                                      itemCount, separator)
 | 
						|
            result = result + memberString
 | 
						|
        return result
 | 
						|
 | 
						|
class CGResolveOwnProperty(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
 | 
						|
                Argument('jsid', 'id'), Argument('bool', 'set'),
 | 
						|
                Argument('JSPropertyDescriptor*', 'desc')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, "ResolveOwnProperty", "bool", args)
 | 
						|
    def definition_body(self):
 | 
						|
        return """  JSObject* obj = wrapper;
 | 
						|
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
 | 
						|
    obj = js::UnwrapObject(obj);
 | 
						|
  }
 | 
						|
  // We rely on getOwnPropertyDescriptor not shadowing prototype properties by named
 | 
						|
  // properties. If that changes we'll need to filter here.
 | 
						|
  return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, set, desc);
 | 
						|
"""
 | 
						|
 | 
						|
class CGEnumerateOwnProperties(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
 | 
						|
                Argument('JS::AutoIdVector&', 'props')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, "EnumerateOwnProperties", "bool", args)
 | 
						|
    def definition_body(self):
 | 
						|
        return """  JSObject* obj = wrapper;
 | 
						|
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
 | 
						|
    obj = js::UnwrapObject(obj);
 | 
						|
  }
 | 
						|
  // We rely on getOwnPropertyNames not shadowing prototype properties by named
 | 
						|
  // properties. If that changes we'll need to filter here.
 | 
						|
  return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
 | 
						|
"""
 | 
						|
 | 
						|
class CGXrayHelper(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor, name, args, properties):
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, name, "bool", args)
 | 
						|
        self.properties = properties
 | 
						|
 | 
						|
    def definition_body(self):
 | 
						|
        varNames = self.properties.variableNames(True)
 | 
						|
 | 
						|
        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
 | 
						|
        else:
 | 
						|
            methodArgs = "NULL, NULL, NULL, 0"
 | 
						|
        methodArgs = CGGeneric(methodArgs)
 | 
						|
 | 
						|
        attrs = self.properties.attrs
 | 
						|
        if attrs.hasNonChromeOnly() or attrs.hasChromeOnly():
 | 
						|
            attrArgs = """// %(attrs)s has an end-of-list marker at the end that we ignore
 | 
						|
%(attrs)s, %(attrs)s_ids, %(attrs)s_specs, ArrayLength(%(attrs)s) - 1""" % varNames
 | 
						|
        else:
 | 
						|
            attrArgs = "NULL, NULL, NULL, 0"
 | 
						|
        attrArgs = CGGeneric(attrArgs)
 | 
						|
 | 
						|
        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
 | 
						|
        else:
 | 
						|
            constArgs = "NULL, NULL, NULL, 0"
 | 
						|
        constArgs = CGGeneric(constArgs)
 | 
						|
 | 
						|
        prefixArgs = CGGeneric(self.getPrefixArgs())
 | 
						|
 | 
						|
        return CGIndenter(
 | 
						|
            CGWrapper(CGList([prefixArgs, methodArgs, attrArgs, constArgs], ",\n"),
 | 
						|
                      pre=("return Xray%s(" % self.name),
 | 
						|
                      post=");",
 | 
						|
                      reindent=True)).define()
 | 
						|
 | 
						|
class CGResolveProperty(CGXrayHelper):
 | 
						|
    def __init__(self, descriptor, properties):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
 | 
						|
                Argument('jsid', 'id'), Argument('bool', 'set'),
 | 
						|
                Argument('JSPropertyDescriptor*', 'desc')]
 | 
						|
        CGXrayHelper.__init__(self, descriptor, "ResolveProperty", args,
 | 
						|
                              properties)
 | 
						|
 | 
						|
    def getPrefixArgs(self):
 | 
						|
        return "cx, wrapper, id, desc"
 | 
						|
 | 
						|
 | 
						|
class CGEnumerateProperties(CGXrayHelper):
 | 
						|
    def __init__(self, descriptor, properties):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
 | 
						|
                Argument('JS::AutoIdVector&', 'props')]
 | 
						|
        CGXrayHelper.__init__(self, descriptor, "EnumerateProperties", args,
 | 
						|
                              properties)
 | 
						|
 | 
						|
    def getPrefixArgs(self):
 | 
						|
        return "props"
 | 
						|
 | 
						|
class CGPrototypeTraitsClass(CGClass):
 | 
						|
    def __init__(self, descriptor, indent=''):
 | 
						|
        templateArgs = [Argument('prototypes::ID', 'PrototypeID')]
 | 
						|
        templateSpecialization = ['prototypes::id::' + descriptor.name]
 | 
						|
        enums = [ClassEnum('', ['Depth'],
 | 
						|
                           [descriptor.interface.inheritanceDepth()])]
 | 
						|
        typedefs = [ClassTypedef('NativeType', descriptor.nativeType)]
 | 
						|
        CGClass.__init__(self, 'PrototypeTraits', indent=indent,
 | 
						|
                         templateArgs=templateArgs,
 | 
						|
                         templateSpecialization=templateSpecialization,
 | 
						|
                         enums=enums, typedefs=typedefs, isStruct=True)
 | 
						|
 | 
						|
class CGPrototypeIDMapClass(CGClass):
 | 
						|
    def __init__(self, descriptor, indent=''):
 | 
						|
        templateArgs = [Argument('class', 'ConcreteClass')]
 | 
						|
        templateSpecialization = [descriptor.nativeType]
 | 
						|
        enums = [ClassEnum('', ['PrototypeID'],
 | 
						|
                           ['prototypes::id::' + descriptor.name])]
 | 
						|
        CGClass.__init__(self, 'PrototypeIDMap', indent=indent,
 | 
						|
                         templateArgs=templateArgs,
 | 
						|
                         templateSpecialization=templateSpecialization,
 | 
						|
                         enums=enums, isStruct=True)
 | 
						|
 | 
						|
class CGClassForwardDeclare(CGThing):
 | 
						|
    def __init__(self, name, isStruct=False):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.name = name
 | 
						|
        self.isStruct = isStruct
 | 
						|
    def declare(self):
 | 
						|
        type = 'struct' if self.isStruct else 'class'
 | 
						|
        return '%s %s;\n' % (type, self.name)
 | 
						|
    def define(self):
 | 
						|
        # Header only
 | 
						|
        return ''
 | 
						|
 | 
						|
class CGProxySpecialOperation(CGPerSignatureCall):
 | 
						|
    """
 | 
						|
    Base class for classes for calling an indexed or named special operation
 | 
						|
    (don't use this directly, use the derived classes below).
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, operation):
 | 
						|
        nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation))
 | 
						|
        operation = descriptor.operations[operation]
 | 
						|
        assert len(operation.signatures()) == 1
 | 
						|
        signature = operation.signatures()[0]
 | 
						|
        extendedAttributes = descriptor.getExtendedAttributes(operation)
 | 
						|
 | 
						|
        (returnType, arguments) = signature
 | 
						|
 | 
						|
        # We pass len(arguments) as the final argument so that the
 | 
						|
        # CGPerSignatureCall won't do any argument conversion of its own.
 | 
						|
        CGPerSignatureCall.__init__(self, returnType, "", arguments, nativeName,
 | 
						|
                                    False, descriptor, operation,
 | 
						|
                                    len(arguments))
 | 
						|
 | 
						|
        if operation.isSetter() or operation.isCreator():
 | 
						|
            # arguments[0] is the index or name of the item that we're setting.
 | 
						|
            argument = arguments[1]
 | 
						|
            template = getJSToNativeConversionTemplate(argument.type, descriptor,
 | 
						|
                                                       treatNullAs=argument.treatNullAs,
 | 
						|
                                                       treatUndefinedAs=argument.treatUndefinedAs)
 | 
						|
            templateValues = {
 | 
						|
                "declName": argument.identifier.name,
 | 
						|
                "holderName": argument.identifier.name + "_holder",
 | 
						|
                "val": "desc->value",
 | 
						|
                "valPtr": "&desc->value"
 | 
						|
            }
 | 
						|
            self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(template, templateValues))
 | 
						|
        elif operation.isGetter():
 | 
						|
            self.cgRoot.prepend(CGGeneric("bool found;"))
 | 
						|
 | 
						|
    def getArguments(self):
 | 
						|
        args = [(a, a.identifier.name) for a in self.arguments]
 | 
						|
        if self.idlNode.isGetter():
 | 
						|
            args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean],
 | 
						|
                                      self.idlNode),
 | 
						|
                         "found"))
 | 
						|
        return args
 | 
						|
 | 
						|
    def wrap_return_value(self):
 | 
						|
        if not self.idlNode.isGetter() or self.templateValues is None:
 | 
						|
            return ""
 | 
						|
 | 
						|
        wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
 | 
						|
        wrap = CGIfWrapper(wrap, "found")
 | 
						|
        return "\n" + wrap.define()
 | 
						|
 | 
						|
class CGProxyIndexedGetter(CGProxySpecialOperation):
 | 
						|
    """
 | 
						|
    Class to generate a call to an indexed getter. If templateValues is not None
 | 
						|
    the returned value will be wrapped with wrapForType using templateValues.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, templateValues=None):
 | 
						|
        self.templateValues = templateValues
 | 
						|
        CGProxySpecialOperation.__init__(self, descriptor, 'IndexedGetter')
 | 
						|
 | 
						|
class CGProxyIndexedSetter(CGProxySpecialOperation):
 | 
						|
    """
 | 
						|
    Class to generate a call to an indexed setter.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter')
 | 
						|
 | 
						|
class CGProxyNamedGetter(CGProxySpecialOperation):
 | 
						|
    """
 | 
						|
    Class to generate a call to an named getter. If templateValues is not None
 | 
						|
    the returned value will be wrapped with wrapForType using templateValues.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor, templateValues=None):
 | 
						|
        self.templateValues = templateValues
 | 
						|
        CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter')
 | 
						|
 | 
						|
class CGProxyNamedSetter(CGProxySpecialOperation):
 | 
						|
    """
 | 
						|
    Class to generate a call to a named setter.
 | 
						|
    """
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter')
 | 
						|
 | 
						|
class CGProxyIsProxy(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSObject*', 'obj')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, "IsProxy", "bool", args, alwaysInline=True)
 | 
						|
    def declare(self):
 | 
						|
        return ""
 | 
						|
    def definition_body(self):
 | 
						|
        return "  return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();"
 | 
						|
 | 
						|
class CGProxyUnwrap(CGAbstractMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSObject*', 'obj')]
 | 
						|
        CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", descriptor.nativeType + '*', args, alwaysInline=True)
 | 
						|
    def declare(self):
 | 
						|
        return ""
 | 
						|
    def definition_body(self):
 | 
						|
        return """  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
 | 
						|
    obj = js::UnwrapObject(obj);
 | 
						|
  }
 | 
						|
  MOZ_ASSERT(IsProxy(obj));
 | 
						|
  return static_cast<%s*>(js::GetProxyPrivate(obj).toPrivate());""" % (self.descriptor.nativeType)
 | 
						|
 | 
						|
class CGDOMJSProxyHandlerDOMClass(CGThing):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGThing.__init__(self)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def declare(self):
 | 
						|
        return "extern const DOMClass Class;\n"
 | 
						|
    def define(self):
 | 
						|
        return """
 | 
						|
const DOMClass Class = """ + DOMClass(self.descriptor) + """;
 | 
						|
 | 
						|
"""
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_CGDOMJSProxyHandler(ClassConstructor):
 | 
						|
    def __init__(self):
 | 
						|
        ClassConstructor.__init__(self, [], inline=True, visibility="private",
 | 
						|
                                  baseConstructors=["mozilla::dom::DOMProxyHandler(Class)"],
 | 
						|
                                  body="")
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
 | 
						|
                Argument('jsid', 'id'), Argument('bool', 'set'),
 | 
						|
                Argument('JSPropertyDescriptor*', 'desc')]
 | 
						|
        ClassMethod.__init__(self, "getOwnPropertyDescriptor", "bool", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        indexedGetter = self.descriptor.operations['IndexedGetter']
 | 
						|
        indexedSetter = self.descriptor.operations['IndexedSetter']
 | 
						|
 | 
						|
        setOrIndexedGet = ""
 | 
						|
        if indexedGetter or indexedSetter:
 | 
						|
            setOrIndexedGet += "int32_t index = GetArrayIndexFromId(cx, id);\n"
 | 
						|
 | 
						|
        if indexedGetter:
 | 
						|
            readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
 | 
						|
            fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
 | 
						|
            templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
 | 
						|
                              'obj': 'proxy', 'successCode': fillDescriptor}
 | 
						|
            get = ("if (index >= 0) {\n" +
 | 
						|
                   "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                   CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
 | 
						|
                   "}\n") % (self.descriptor.nativeType)
 | 
						|
 | 
						|
        if indexedSetter or self.descriptor.operations['NamedSetter']:
 | 
						|
            setOrIndexedGet += "if (set) {\n"
 | 
						|
            if indexedSetter:
 | 
						|
                setOrIndexedGet += ("  if (index >= 0) {\n")
 | 
						|
                if not 'IndexedCreator' in self.descriptor.operations:
 | 
						|
                    # FIXME need to check that this is a 'supported property index'
 | 
						|
                    assert False
 | 
						|
                setOrIndexedGet += ("    FillPropertyDescriptor(desc, proxy, JSVAL_VOID, false);\n" +
 | 
						|
                                    "    return true;\n" +
 | 
						|
                                    "  }\n")
 | 
						|
            if self.descriptor.operations['NamedSetter']:
 | 
						|
                setOrIndexedGet += "  if (JSID_IS_STRING(id)) {\n"
 | 
						|
                if not 'NamedCreator' in self.descriptor.operations:
 | 
						|
                    # FIXME need to check that this is a 'supported property name'
 | 
						|
                    assert False
 | 
						|
                setOrIndexedGet += ("    FillPropertyDescriptor(desc, proxy, JSVAL_VOID, false);\n" +
 | 
						|
                                    "    return true;\n" +
 | 
						|
                                    "  }\n")
 | 
						|
            setOrIndexedGet += "}"
 | 
						|
            if indexedGetter:
 | 
						|
                setOrIndexedGet += (" else {\n" +
 | 
						|
                                    CGIndenter(CGGeneric(get)).define() +
 | 
						|
                                    "}")
 | 
						|
            setOrIndexedGet += "\n\n"
 | 
						|
        elif indexedGetter:
 | 
						|
            setOrIndexedGet += ("if (!set) {\n" +
 | 
						|
                                CGIndenter(CGGeneric(get)).define() +
 | 
						|
                                "}\n\n")
 | 
						|
 | 
						|
        namedGetter = self.descriptor.operations['NamedGetter']
 | 
						|
        if namedGetter:
 | 
						|
            readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
 | 
						|
            fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
 | 
						|
            templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
 | 
						|
                              'obj': 'proxy', 'successCode': fillDescriptor}
 | 
						|
            # Once we start supporting OverrideBuiltins we need to make
 | 
						|
            # ResolveOwnProperty or EnumerateOwnProperties filter out named
 | 
						|
            # properties that shadow prototype properties.
 | 
						|
            namedGet = ("\n" +
 | 
						|
                        "if (!set && JSID_IS_STRING(id) && !HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
 | 
						|
                        "  JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
 | 
						|
                        "  FakeDependentString name;\n"
 | 
						|
                        "  if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
 | 
						|
                        "                              eStringify, eStringify, name)) {\n" +
 | 
						|
                        "    return false;\n" +
 | 
						|
                        "  }\n" +
 | 
						|
                        "\n" +
 | 
						|
                        "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                        CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" +
 | 
						|
                        "}\n") % (self.descriptor.nativeType)
 | 
						|
        else:
 | 
						|
            namedGet = ""
 | 
						|
 | 
						|
        return setOrIndexedGet + """JSObject* expando;
 | 
						|
if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
 | 
						|
  unsigned flags = (set ? JSRESOLVE_ASSIGNING : 0) | JSRESOLVE_QUALIFIED;
 | 
						|
  if (!JS_GetPropertyDescriptorById(cx, expando, id, flags, desc)) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  if (desc->obj) {
 | 
						|
    // Pretend the property lives on the wrapper.
 | 
						|
    desc->obj = proxy;
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
}
 | 
						|
""" + namedGet + """
 | 
						|
desc->obj = NULL;
 | 
						|
return true;"""
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_defineProperty(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
 | 
						|
                Argument('jsid', 'id'),
 | 
						|
                Argument('JSPropertyDescriptor*', 'desc')]
 | 
						|
        ClassMethod.__init__(self, "defineProperty", "bool", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        set = ""
 | 
						|
 | 
						|
        indexedSetter = self.descriptor.operations['IndexedSetter']
 | 
						|
        if indexedSetter:
 | 
						|
            if not (self.descriptor.operations['IndexedCreator'] is indexedSetter):
 | 
						|
                raise TypeError("Can't handle creator that's different from the setter")
 | 
						|
            set += ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
 | 
						|
                    "if (index >= 0) {\n" +
 | 
						|
                    "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                    CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() +
 | 
						|
                    "  return true;\n" +
 | 
						|
                    "}\n") % (self.descriptor.nativeType)
 | 
						|
        elif self.descriptor.operations['IndexedGetter']:
 | 
						|
            set += ("if (GetArrayIndexFromId(cx, id) >= 0) {\n" +
 | 
						|
                    "  return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
 | 
						|
                    "}\n") % self.descriptor.name
 | 
						|
 | 
						|
        namedSetter = self.descriptor.operations['NamedSetter']
 | 
						|
        if namedSetter:
 | 
						|
            if not self.descriptor.operations['NamedCreator'] is namedSetter:
 | 
						|
                raise TypeError("Can't handle creator that's different from the setter")
 | 
						|
            set += ("if (JSID_IS_STRING(id)) {\n" +
 | 
						|
                    "  JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
 | 
						|
                    "  FakeDependentString name;\n"
 | 
						|
                    "  if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
 | 
						|
                    "                              eStringify, eStringify, name)) {\n" +
 | 
						|
                    "    return false;\n" +
 | 
						|
                    "  }\n" +
 | 
						|
                    "\n" +
 | 
						|
                    "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                    CGIndenter(CGProxyNamedSetter(self.descriptor)).define() + "\n" +
 | 
						|
                    "}\n") % (self.descriptor.nativeType)
 | 
						|
        elif self.descriptor.operations['NamedGetter']:
 | 
						|
            set += ("if (JSID_IS_STRING(id)) {\n" +
 | 
						|
                    "  JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
 | 
						|
                    "  FakeDependentString name;\n"
 | 
						|
                    "  if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
 | 
						|
                    "                              eStringify, eStringify, name)) {\n" +
 | 
						|
                    "    return false;\n" +
 | 
						|
                    "  }\n" +
 | 
						|
                    "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                    CGIndenter(CGProxyNamedGetter(self.descriptor)).define() +
 | 
						|
                    "  if (found) {\n"
 | 
						|
                    "    return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
 | 
						|
                    "  }\n" +
 | 
						|
                    "  return true;\n"
 | 
						|
                    "}\n") % (self.descriptor.nativeType, self.descriptor.name)
 | 
						|
        return set + """return mozilla::dom::DOMProxyHandler::defineProperty(%s);""" % ", ".join(a.name for a in self.args)
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_getOwnPropertyNames(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
 | 
						|
                Argument('JS::AutoIdVector&', 'props')]
 | 
						|
        ClassMethod.__init__(self, "getOwnPropertyNames", "bool", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        indexedGetter = self.descriptor.operations['IndexedGetter']
 | 
						|
        if indexedGetter:
 | 
						|
            addIndices = """uint32_t length = UnwrapProxy(proxy)->Length();
 | 
						|
MOZ_ASSERT(int32_t(length) >= 0);
 | 
						|
for (int32_t i = 0; i < int32_t(length); ++i) {
 | 
						|
  if (!props.append(INT_TO_JSID(i))) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
"""
 | 
						|
        else:
 | 
						|
            addIndices = ""
 | 
						|
 | 
						|
        return addIndices + """JSObject* expando;
 | 
						|
if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
 | 
						|
    !js::GetPropertyNames(cx, expando, JSITER_OWNONLY | JSITER_HIDDEN, &props)) {
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
// FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=772869 Add named items
 | 
						|
return true;"""
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_hasOwn(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
 | 
						|
                Argument('jsid', 'id'), Argument('bool*', 'bp')]
 | 
						|
        ClassMethod.__init__(self, "hasOwn", "bool", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        indexedGetter = self.descriptor.operations['IndexedGetter']
 | 
						|
        if indexedGetter:
 | 
						|
            indexed = ("int32_t index = GetArrayIndexFromId(cx, id);\n" + 
 | 
						|
                       "if (index >= 0) {\n" +
 | 
						|
                       "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                       CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" +
 | 
						|
                       "  *bp = found;\n" +
 | 
						|
                       "  return true;\n" +
 | 
						|
                       "}\n\n") % (self.descriptor.nativeType)
 | 
						|
        else:
 | 
						|
            indexed = ""
 | 
						|
 | 
						|
        namedGetter = self.descriptor.operations['NamedGetter']
 | 
						|
        if namedGetter:
 | 
						|
            named = ("if (JSID_IS_STRING(id) && !HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
 | 
						|
                     "  jsval nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
 | 
						|
                     "  FakeDependentString name;\n"
 | 
						|
                     "  if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
 | 
						|
                     "                              eStringify, eStringify, name)) {\n" +
 | 
						|
                     "    return false;\n" +
 | 
						|
                     "  }\n" +
 | 
						|
                     "\n" +
 | 
						|
                     "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                     CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" +
 | 
						|
                     "  *bp = found;\n"
 | 
						|
                     "  return true;\n"
 | 
						|
                     "}\n" +
 | 
						|
                     "\n") % (self.descriptor.nativeType)
 | 
						|
        else:
 | 
						|
            named = ""
 | 
						|
 | 
						|
        return indexed + """JSObject* expando = GetExpandoObject(proxy);
 | 
						|
if (expando) {
 | 
						|
  JSBool b = true;
 | 
						|
  JSBool ok = JS_HasPropertyById(cx, expando, id, &b);
 | 
						|
  *bp = !!b;
 | 
						|
  if (!ok || *bp) {
 | 
						|
    return ok;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
""" + named + """*bp = false;
 | 
						|
return true;"""
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_get(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
 | 
						|
                Argument('JSObject*', 'receiver'), Argument('jsid', 'id'),
 | 
						|
                Argument('JS::Value*', 'vp')]
 | 
						|
        ClassMethod.__init__(self, "get", "bool", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        getFromExpando = """JSObject* expando = DOMProxyHandler::GetExpandoObject(proxy);
 | 
						|
if (expando) {
 | 
						|
  JSBool hasProp;
 | 
						|
  if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  if (hasProp) {
 | 
						|
    return JS_GetPropertyById(cx, expando, id, vp);
 | 
						|
  }
 | 
						|
}"""
 | 
						|
 | 
						|
        templateValues = {'jsvalRef': '*vp', 'jsvalPtr': 'vp', 'obj': 'proxy'}
 | 
						|
 | 
						|
        indexedGetter = self.descriptor.operations['IndexedGetter']
 | 
						|
        if indexedGetter:
 | 
						|
            getIndexedOrExpando = ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
 | 
						|
                                   "if (index >= 0) {\n" +
 | 
						|
                                   "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                                   CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()) % (self.descriptor.nativeType)
 | 
						|
            getIndexedOrExpando += """
 | 
						|
  // Even if we don't have this index, we don't forward the
 | 
						|
  // get on to our expando object.
 | 
						|
} else {
 | 
						|
  %s
 | 
						|
}
 | 
						|
""" % (stripTrailingWhitespace(getFromExpando.replace('\n', '\n  ')))
 | 
						|
        else:
 | 
						|
            getIndexedOrExpando = getFromExpando + "\n"
 | 
						|
 | 
						|
        namedGetter = self.descriptor.operations['NamedGetter']
 | 
						|
        if namedGetter:
 | 
						|
            getNamed = ("if (JSID_IS_STRING(id)) {\n" +
 | 
						|
                        "  JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
 | 
						|
                        "  FakeDependentString name;\n"
 | 
						|
                        "  if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
 | 
						|
                        "                              eStringify, eStringify, name)) {\n" +
 | 
						|
                        "    return false;\n" +
 | 
						|
                        "  }\n" +
 | 
						|
                        "\n" +
 | 
						|
                        "  %s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                        CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
 | 
						|
                        "}\n") % (self.descriptor.nativeType)
 | 
						|
        else:
 | 
						|
            getNamed = ""
 | 
						|
 | 
						|
        return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
 | 
						|
            "Should not have a XrayWrapper here");
 | 
						|
 | 
						|
%s
 | 
						|
bool found;
 | 
						|
if (!GetPropertyOnPrototype(cx, proxy, id, &found, vp)) {
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
if (found) {
 | 
						|
  return true;
 | 
						|
}
 | 
						|
%s
 | 
						|
vp->setUndefined();
 | 
						|
return true;""" % (getIndexedOrExpando, getNamed)
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_obj_toString(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy')]
 | 
						|
        ClassMethod.__init__(self, "obj_toString", "JSString*", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        stringifier = self.descriptor.operations['Stringifier']
 | 
						|
        if stringifier:
 | 
						|
            name = stringifier.identifier.name
 | 
						|
            nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
 | 
						|
            signature = stringifier.signatures()[0]
 | 
						|
            returnType = signature[0]
 | 
						|
            extendedAttributes = self.descriptor.getExtendedAttributes(stringifier)
 | 
						|
            infallible = 'infallible' in extendedAttributes
 | 
						|
            if not infallible:
 | 
						|
                error = CGGeneric(
 | 
						|
                    ('ThrowMethodFailedWithDetails(cx, rv, "%s", "toString");\n' +
 | 
						|
                     "return NULL;") % self.descriptor.interface.identifier.name)
 | 
						|
            else:
 | 
						|
                error = None
 | 
						|
            call = CGCallGenerator(error, [], "", returnType, extendedAttributes, self.descriptor, nativeName, False, object="UnwrapProxy(proxy)")
 | 
						|
            return call.define() + """
 | 
						|
 | 
						|
JSString* jsresult;
 | 
						|
return xpc_qsStringToJsstring(cx, result, &jsresult) ? jsresult : NULL;""" 
 | 
						|
 | 
						|
        return "return mozilla::dom::DOMProxyHandler::obj_toString(cx, \"%s\");" % self.descriptor.name
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_finalize(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'proxy')]
 | 
						|
        ClassMethod.__init__(self, "finalize", "void", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") +
 | 
						|
                finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name))
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_getElementIfPresent(ClassMethod):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
 | 
						|
                Argument('JSObject*', 'receiver'),
 | 
						|
                Argument('uint32_t', 'index'),
 | 
						|
                Argument('JS::Value*', 'vp'), Argument('bool*', 'present')]
 | 
						|
        ClassMethod.__init__(self, "getElementIfPresent", "bool", args)
 | 
						|
        self.descriptor = descriptor
 | 
						|
    def getBody(self):
 | 
						|
        indexedGetter = self.descriptor.operations['IndexedGetter']
 | 
						|
        if indexedGetter:
 | 
						|
            successCode = """*present = found;
 | 
						|
return true;"""
 | 
						|
            templateValues = {'jsvalRef': '*vp', 'jsvalPtr': 'vp',
 | 
						|
                              'obj': 'proxy', 'successCode': successCode}
 | 
						|
            get = ("%s* self = UnwrapProxy(proxy);\n" +
 | 
						|
                   CGProxyIndexedGetter(self.descriptor, templateValues).define() + "\n"
 | 
						|
                   "// We skip the expando object if there is an indexed getter.\n" +
 | 
						|
                   "\n") % (self.descriptor.nativeType)
 | 
						|
        else:
 | 
						|
            get = """
 | 
						|
 | 
						|
JSObject* expando = GetExpandoObject(proxy);
 | 
						|
if (expando) {
 | 
						|
  JSBool isPresent;
 | 
						|
  if (!JS_GetElementIfPresent(cx, expando, index, expando, vp, &isPresent)) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  if (isPresent) {
 | 
						|
    *present = true;
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
}
 | 
						|
"""
 | 
						|
 | 
						|
        return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
 | 
						|
             "Should not have a XrayWrapper here");
 | 
						|
 | 
						|
""" + get + """
 | 
						|
// No need to worry about name getters here, so just check the proto.
 | 
						|
 | 
						|
JSObject *proto;
 | 
						|
if (!js::GetObjectProto(cx, proxy, &proto)) {
 | 
						|
  return false;
 | 
						|
}
 | 
						|
if (proto) {
 | 
						|
  JSBool isPresent;
 | 
						|
  if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  *present = isPresent;
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
*present = false;
 | 
						|
// Can't Debug_SetValueRangeToCrashOnTouch because it's not public
 | 
						|
return true;"""
 | 
						|
 | 
						|
class CGDOMJSProxyHandler_getInstance(ClassMethod):
 | 
						|
    def __init__(self):
 | 
						|
        ClassMethod.__init__(self, "getInstance", "DOMProxyHandler*", [], static=True)
 | 
						|
    def getBody(self):
 | 
						|
        return """static DOMProxyHandler instance;
 | 
						|
return &instance;"""
 | 
						|
 | 
						|
class CGDOMJSProxyHandler(CGClass):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        constructors = [CGDOMJSProxyHandler_CGDOMJSProxyHandler()]
 | 
						|
        methods = [CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor)]
 | 
						|
        if descriptor.operations['IndexedSetter'] or descriptor.operations['NamedSetter']:
 | 
						|
            methods.append(CGDOMJSProxyHandler_defineProperty(descriptor))
 | 
						|
        methods.extend([CGDOMJSProxyHandler_getOwnPropertyNames(descriptor),
 | 
						|
                        CGDOMJSProxyHandler_hasOwn(descriptor),
 | 
						|
                        CGDOMJSProxyHandler_get(descriptor),
 | 
						|
                        CGDOMJSProxyHandler_obj_toString(descriptor),
 | 
						|
                        CGDOMJSProxyHandler_finalize(descriptor),
 | 
						|
                        CGDOMJSProxyHandler_getElementIfPresent(descriptor),
 | 
						|
                        CGDOMJSProxyHandler_getInstance()])
 | 
						|
        CGClass.__init__(self, 'DOMProxyHandler',
 | 
						|
                         bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
 | 
						|
                         constructors=constructors,
 | 
						|
                         methods=methods)
 | 
						|
 | 
						|
def stripTrailingWhitespace(text):
 | 
						|
    tail = '\n' if text.endswith('\n') else ''
 | 
						|
    lines = text.splitlines()
 | 
						|
    for i in range(len(lines)):
 | 
						|
        lines[i] = lines[i].rstrip()
 | 
						|
    return '\n'.join(lines) + tail
 | 
						|
 | 
						|
class CGDescriptor(CGThing):
 | 
						|
    def __init__(self, descriptor):
 | 
						|
        CGThing.__init__(self)
 | 
						|
 | 
						|
        assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
 | 
						|
 | 
						|
        cgThings = []
 | 
						|
        if descriptor.interface.hasInterfacePrototypeObject():
 | 
						|
            (hasMethod, hasGetter, hasLenientGetter,
 | 
						|
             hasSetter, hasLenientSetter) = False, False, False, False, False
 | 
						|
            for m in descriptor.interface.members:
 | 
						|
                if m.isMethod() and not m.isStatic() and not m.isIdentifierLess():
 | 
						|
                    cgThings.append(CGSpecializedMethod(descriptor, m))
 | 
						|
                    cgThings.append(CGMemberJITInfo(descriptor, m))
 | 
						|
                    hasMethod = True
 | 
						|
                elif m.isAttr():
 | 
						|
                    cgThings.append(CGSpecializedGetter(descriptor, m))
 | 
						|
                    if m.hasLenientThis():
 | 
						|
                        hasLenientGetter = True
 | 
						|
                    else:
 | 
						|
                        hasGetter = True
 | 
						|
                    if not m.readonly:
 | 
						|
                        cgThings.append(CGSpecializedSetter(descriptor, m))
 | 
						|
                        if m.hasLenientThis():
 | 
						|
                            hasLenientSetter = True
 | 
						|
                        else:
 | 
						|
                            hasSetter = True
 | 
						|
                    cgThings.append(CGMemberJITInfo(descriptor, m))
 | 
						|
            if hasMethod: cgThings.append(CGGenericMethod(descriptor))
 | 
						|
            if hasGetter: cgThings.append(CGGenericGetter(descriptor))
 | 
						|
            if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor,
 | 
						|
                                                                 lenientThis=True))
 | 
						|
            if hasSetter: cgThings.append(CGGenericSetter(descriptor))
 | 
						|
            if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor,
 | 
						|
                                                                 lenientThis=True))
 | 
						|
 | 
						|
        if descriptor.concrete and not descriptor.proxy:
 | 
						|
            if not descriptor.workers and descriptor.wrapperCache:
 | 
						|
                cgThings.append(CGAddPropertyHook(descriptor))
 | 
						|
 | 
						|
            # Always have a finalize hook, regardless of whether the class wants a
 | 
						|
            # custom hook.
 | 
						|
            cgThings.append(CGClassFinalizeHook(descriptor))
 | 
						|
 | 
						|
            # Only generate a trace hook if the class wants a custom hook.
 | 
						|
            if (descriptor.customTrace):
 | 
						|
                cgThings.append(CGClassTraceHook(descriptor))
 | 
						|
 | 
						|
        if descriptor.interface.hasInterfaceObject():
 | 
						|
            cgThings.append(CGClassConstructHook(descriptor))
 | 
						|
            cgThings.append(CGClassHasInstanceHook(descriptor))
 | 
						|
            cgThings.append(CGInterfaceObjectJSClass(descriptor))
 | 
						|
 | 
						|
        if descriptor.interface.hasInterfacePrototypeObject():
 | 
						|
            cgThings.append(CGPrototypeJSClass(descriptor))
 | 
						|
 | 
						|
        properties = PropertyArrays(descriptor)
 | 
						|
        cgThings.append(CGGeneric(define=str(properties)))
 | 
						|
        cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
 | 
						|
        if descriptor.interface.hasInterfacePrototypeObject():
 | 
						|
            cgThings.append(CGGetProtoObjectMethod(descriptor))
 | 
						|
        else:
 | 
						|
            cgThings.append(CGGetConstructorObjectMethod(descriptor))
 | 
						|
 | 
						|
        # Set up our Xray callbacks as needed.  Note that we don't need to do
 | 
						|
        # it in workers.
 | 
						|
        if (descriptor.interface.hasInterfacePrototypeObject() and
 | 
						|
            not descriptor.workers):
 | 
						|
            if descriptor.concrete and descriptor.proxy:
 | 
						|
                cgThings.append(CGResolveOwnProperty(descriptor))
 | 
						|
                cgThings.append(CGEnumerateOwnProperties(descriptor))
 | 
						|
            cgThings.append(CGResolveProperty(descriptor, properties))
 | 
						|
            cgThings.append(CGEnumerateProperties(descriptor, properties))
 | 
						|
 | 
						|
        if descriptor.interface.hasInterfaceObject():
 | 
						|
            cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
 | 
						|
            if (not descriptor.interface.isExternal() and
 | 
						|
                # Workers stuff is never pref-controlled
 | 
						|
                not descriptor.workers and
 | 
						|
                descriptor.interface.getExtendedAttribute("PrefControlled") is not None):
 | 
						|
                cgThings.append(CGPrefEnabled(descriptor))
 | 
						|
 | 
						|
        if descriptor.interface.hasInterfacePrototypeObject():
 | 
						|
            cgThings.append(CGNativePropertyHooks(descriptor))
 | 
						|
 | 
						|
        if descriptor.concrete:
 | 
						|
            if descriptor.proxy:
 | 
						|
                cgThings.append(CGProxyIsProxy(descriptor))
 | 
						|
                cgThings.append(CGProxyUnwrap(descriptor))
 | 
						|
                cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor))
 | 
						|
                cgThings.append(CGDOMJSProxyHandler(descriptor))
 | 
						|
                cgThings.append(CGIsMethod(descriptor))
 | 
						|
            else:
 | 
						|
                cgThings.append(CGDOMJSClass(descriptor))
 | 
						|
 | 
						|
            if descriptor.wrapperCache:
 | 
						|
                cgThings.append(CGWrapWithCacheMethod(descriptor))
 | 
						|
                cgThings.append(CGWrapMethod(descriptor))
 | 
						|
            else:
 | 
						|
                cgThings.append(CGWrapNonWrapperCacheMethod(descriptor))
 | 
						|
 | 
						|
        cgThings = CGList((CGIndenter(t, declareOnly=True) for t in cgThings), "\n")
 | 
						|
        cgThings = CGWrapper(cgThings, pre='\n', post='\n')
 | 
						|
        self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
 | 
						|
                                            cgThings),
 | 
						|
                                post='\n')
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        return self.cgRoot.declare()
 | 
						|
    def define(self):
 | 
						|
        return self.cgRoot.define()
 | 
						|
 | 
						|
class CGNamespacedEnum(CGThing):
 | 
						|
    def __init__(self, namespace, enumName, names, values, comment=""):
 | 
						|
 | 
						|
        if not values:
 | 
						|
            values = []
 | 
						|
 | 
						|
        # Account for explicit enum values.
 | 
						|
        entries = []
 | 
						|
        for i in range(0, len(names)):
 | 
						|
            if len(values) > i and values[i] is not None:
 | 
						|
                entry = "%s = %s" % (names[i], values[i])
 | 
						|
            else:
 | 
						|
                entry = names[i]
 | 
						|
            entries.append(entry)
 | 
						|
 | 
						|
        # Append a Count.
 | 
						|
        entries.append('_' + enumName + '_Count')
 | 
						|
 | 
						|
        # Indent.
 | 
						|
        entries = ['  ' + e for e in entries]
 | 
						|
 | 
						|
        # Build the enum body.
 | 
						|
        enumstr = comment + 'enum %s\n{\n%s\n};\n' % (enumName, ',\n'.join(entries))
 | 
						|
        curr = CGGeneric(declare=enumstr)
 | 
						|
 | 
						|
        # Add some whitespace padding.
 | 
						|
        curr = CGWrapper(curr, pre='\n',post='\n')
 | 
						|
 | 
						|
        # Add the namespace.
 | 
						|
        curr = CGNamespace(namespace, curr)
 | 
						|
 | 
						|
        # Add the typedef
 | 
						|
        typedef = '\ntypedef %s::%s %s;\n\n' % (namespace, enumName, enumName)
 | 
						|
        curr = CGList([curr, CGGeneric(declare=typedef)])
 | 
						|
 | 
						|
        # Save the result.
 | 
						|
        self.node = curr
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        return self.node.declare()
 | 
						|
    def define(self):
 | 
						|
        assert False # Only for headers.
 | 
						|
 | 
						|
class CGDictionary(CGThing):
 | 
						|
    def __init__(self, dictionary, descriptorProvider):
 | 
						|
        self.dictionary = dictionary;
 | 
						|
        self.workers = descriptorProvider.workers
 | 
						|
        if all(CGDictionary(d, descriptorProvider).generatable for
 | 
						|
               d in CGDictionary.getDictionaryDependencies(dictionary)):
 | 
						|
            self.generatable = True
 | 
						|
        else:
 | 
						|
            self.generatable = False
 | 
						|
            # Nothing else to do here
 | 
						|
            return
 | 
						|
        # Getting a conversion template for interface types can fail
 | 
						|
        # if we don't have a relevant descriptor when self.workers is True.
 | 
						|
        # If that happens, just mark ourselves as not being
 | 
						|
        # generatable and move on.
 | 
						|
        try:
 | 
						|
            self.memberInfo = [
 | 
						|
                (member,
 | 
						|
                 getJSToNativeConversionTemplate(member.type,
 | 
						|
                                                 descriptorProvider,
 | 
						|
                                                 isMember=True,
 | 
						|
                                                 isOptional=(not member.defaultValue),
 | 
						|
                                                 defaultValue=member.defaultValue))
 | 
						|
                for member in dictionary.members ]
 | 
						|
        except NoSuchDescriptorError, err:
 | 
						|
            if not self.workers:
 | 
						|
                raise err
 | 
						|
            self.generatable = False
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        if not self.generatable:
 | 
						|
            return ""
 | 
						|
        d = self.dictionary
 | 
						|
        if d.parent:
 | 
						|
            inheritance = ": public %s " % self.makeClassName(d.parent)
 | 
						|
        else:
 | 
						|
            inheritance = ""
 | 
						|
        memberDecls = ["  %s %s;" %
 | 
						|
                       (self.getMemberType(m), m[0].identifier.name)
 | 
						|
                       for m in self.memberInfo]
 | 
						|
 | 
						|
        return (string.Template(
 | 
						|
                "struct ${selfName} ${inheritance}{\n"
 | 
						|
                "  ${selfName}() {}\n"
 | 
						|
                "  bool Init(JSContext* cx, const JS::Value& val);\n"
 | 
						|
                "\n" +
 | 
						|
                "\n".join(memberDecls) + "\n"
 | 
						|
                "private:\n"
 | 
						|
                "  // Disallow copy-construction\n"
 | 
						|
                "  ${selfName}(const ${selfName}&) MOZ_DELETE;\n" +
 | 
						|
                # NOTE: jsids are per-runtime, so don't use them in workers
 | 
						|
                ("  static bool InitIds(JSContext* cx);\n"
 | 
						|
                 "  static bool initedIds;\n" if not self.workers else "") +
 | 
						|
                "\n".join("  static jsid " +
 | 
						|
                          self.makeIdName(m.identifier.name) + ";" for
 | 
						|
                          m in d.members) + "\n"
 | 
						|
                "};").substitute( { "selfName": self.makeClassName(d),
 | 
						|
                                    "inheritance": inheritance }))
 | 
						|
 | 
						|
    def define(self):
 | 
						|
        if not self.generatable:
 | 
						|
            return ""
 | 
						|
        d = self.dictionary
 | 
						|
        if d.parent:
 | 
						|
            initParent = ("// Per spec, we init the parent's members first\n"
 | 
						|
                          "if (!%s::Init(cx, val)) {\n"
 | 
						|
                          "  return false;\n"
 | 
						|
                          "}\n" % self.makeClassName(d.parent))
 | 
						|
        else:
 | 
						|
            initParent = ""
 | 
						|
 | 
						|
        memberInits = [CGIndenter(self.getMemberConversion(m)).define()
 | 
						|
                       for m in self.memberInfo]
 | 
						|
        idinit = [CGGeneric('!InternJSString(cx, %s, "%s")' %
 | 
						|
                            (m.identifier.name + "_id", m.identifier.name))
 | 
						|
                  for m in d.members]
 | 
						|
        idinit = CGList(idinit, " ||\n")
 | 
						|
        idinit = CGWrapper(idinit, pre="if (",
 | 
						|
                           post=(") {\n"
 | 
						|
                                 "  return false;\n"
 | 
						|
                                 "}"),
 | 
						|
                           reindent=True)
 | 
						|
 | 
						|
        return string.Template(
 | 
						|
            # NOTE: jsids are per-runtime, so don't use them in workers
 | 
						|
            ("bool ${selfName}::initedIds = false;\n" +
 | 
						|
             "\n".join("jsid ${selfName}::%s = JSID_VOID;" %
 | 
						|
                       self.makeIdName(m.identifier.name)
 | 
						|
                       for m in d.members) + "\n"
 | 
						|
             "\n"
 | 
						|
             "bool\n"
 | 
						|
             "${selfName}::InitIds(JSContext* cx)\n"
 | 
						|
             "{\n"
 | 
						|
             "  MOZ_ASSERT(!initedIds);\n"
 | 
						|
             "${idInit}\n"
 | 
						|
             "  initedIds = true;\n"
 | 
						|
             "  return true;\n"
 | 
						|
             "}\n"
 | 
						|
             "\n" if not self.workers else "") +
 | 
						|
            "bool\n"
 | 
						|
            "${selfName}::Init(JSContext* cx, const JS::Value& val)\n"
 | 
						|
            "{\n" +
 | 
						|
            # NOTE: jsids are per-runtime, so don't use them in workers
 | 
						|
            ("  if (!initedIds && !InitIds(cx)) {\n"
 | 
						|
             "    return false;\n"
 | 
						|
             "  }\n" if not self.workers else "") +
 | 
						|
            "${initParent}"
 | 
						|
            "  JSBool found;\n"
 | 
						|
            "  JS::Value temp;\n"
 | 
						|
            "  bool isNull = val.isNullOrUndefined();\n"
 | 
						|
            "  if (!isNull && !val.isObject()) {\n"
 | 
						|
            "    return Throw<${isMainThread}>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
 | 
						|
            "  }\n"
 | 
						|
            "\n"
 | 
						|
            "${initMembers}\n"
 | 
						|
            "  return true;\n"
 | 
						|
            "}").substitute({
 | 
						|
                "selfName": self.makeClassName(d),
 | 
						|
                "initParent": CGIndenter(CGGeneric(initParent)).define(),
 | 
						|
                "initMembers": "\n\n".join(memberInits),
 | 
						|
                "idInit": CGIndenter(idinit).define(),
 | 
						|
                "isMainThread": toStringBool(not self.workers)
 | 
						|
                })
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def makeDictionaryName(dictionary, workers):
 | 
						|
        suffix = "Workers" if workers else ""
 | 
						|
        return dictionary.identifier.name + suffix
 | 
						|
 | 
						|
    def makeClassName(self, dictionary):
 | 
						|
        return self.makeDictionaryName(dictionary, self.workers)
 | 
						|
 | 
						|
    def getMemberType(self, memberInfo):
 | 
						|
        (member, (templateBody, declType,
 | 
						|
                  holderType, dealWithOptional)) = memberInfo
 | 
						|
        # We can't handle having a holderType here
 | 
						|
        assert holderType is None
 | 
						|
        if dealWithOptional:
 | 
						|
            declType = CGWrapper(declType, pre="Optional< ", post=" >")
 | 
						|
        return declType.define()
 | 
						|
 | 
						|
    def getMemberConversion(self, memberInfo):
 | 
						|
        (member, (templateBody, declType,
 | 
						|
                  holderType, dealWithOptional)) = memberInfo
 | 
						|
        replacements = { "val": "temp",
 | 
						|
                         "valPtr": "&temp",
 | 
						|
                         # Use this->%s to refer to members, because we don't
 | 
						|
                         # control the member names and want to make sure we're
 | 
						|
                         # talking about the member, not some local that
 | 
						|
                         # shadows the member.  Another option would be to move
 | 
						|
                         # the guts of init to a static method which is passed
 | 
						|
                         # an explicit reference to our dictionary object, so
 | 
						|
                         # we couldn't screw this up even if we wanted to....
 | 
						|
                         "declName": ("(this->%s)" % member.identifier.name),
 | 
						|
                         # We need a holder name for external interfaces, but
 | 
						|
                         # it's scoped down to the conversion so we can just use
 | 
						|
                         # anything we want.
 | 
						|
                         "holderName": "holder"}
 | 
						|
        # We can't handle having a holderType here
 | 
						|
        assert holderType is None
 | 
						|
        if dealWithOptional:
 | 
						|
            replacements["declName"] = "(" + replacements["declName"] + ".Value())"
 | 
						|
        if member.defaultValue:
 | 
						|
            replacements["haveValue"] = "found"
 | 
						|
 | 
						|
        # NOTE: jsids are per-runtime, so don't use them in workers
 | 
						|
        if self.workers:
 | 
						|
            propName = member.identifier.name
 | 
						|
            propCheck = ('JS_HasProperty(cx, &val.toObject(), "%s", &found)' %
 | 
						|
                         propName)
 | 
						|
            propGet = ('JS_GetProperty(cx, &val.toObject(), "%s", &temp)' %
 | 
						|
                       propName)
 | 
						|
        else:
 | 
						|
            propId = self.makeIdName(member.identifier.name);
 | 
						|
            propCheck = ("JS_HasPropertyById(cx, &val.toObject(), %s, &found)" %
 | 
						|
                         propId)
 | 
						|
            propGet = ("JS_GetPropertyById(cx, &val.toObject(), %s, &temp)" %
 | 
						|
                       propId)
 | 
						|
 | 
						|
        conversionReplacements = {
 | 
						|
            "prop": "(this->%s)" % member.identifier.name,
 | 
						|
            "convert": string.Template(templateBody).substitute(replacements),
 | 
						|
            "propCheck": propCheck,
 | 
						|
            "propGet": propGet
 | 
						|
            }
 | 
						|
        conversion = ("if (isNull) {\n"
 | 
						|
                      "  found = false;\n"
 | 
						|
                      "} else if (!${propCheck}) {\n"
 | 
						|
                      "  return false;\n"
 | 
						|
                      "}\n")
 | 
						|
        if member.defaultValue:
 | 
						|
            conversion += (
 | 
						|
                "if (found) {\n"
 | 
						|
                "  if (!${propGet}) {\n"
 | 
						|
                "    return false;\n"
 | 
						|
                "  }\n"
 | 
						|
                "}\n"
 | 
						|
                "${convert}")
 | 
						|
        else:
 | 
						|
            conversion += (
 | 
						|
                "if (found) {\n"
 | 
						|
                "  ${prop}.Construct();\n"
 | 
						|
                "  if (!${propGet}) {\n"
 | 
						|
                "    return false;\n"
 | 
						|
                "  }\n"
 | 
						|
                "${convert}\n"
 | 
						|
                "}")
 | 
						|
            conversionReplacements["convert"] = CGIndenter(
 | 
						|
                CGGeneric(conversionReplacements["convert"])).define()
 | 
						|
        
 | 
						|
        return CGGeneric(
 | 
						|
            string.Template(conversion).substitute(conversionReplacements)
 | 
						|
            )
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def makeIdName(name):
 | 
						|
        return name + "_id"
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def getDictionaryDependencies(dictionary):
 | 
						|
        deps = set();
 | 
						|
        if dictionary.parent:
 | 
						|
            deps.add(dictionary.parent)
 | 
						|
        for member in dictionary.members:
 | 
						|
            if member.type.isDictionary():
 | 
						|
                deps.add(member.type.unroll().inner)
 | 
						|
        return deps
 | 
						|
 | 
						|
 | 
						|
class CGRegisterProtos(CGAbstractMethod):
 | 
						|
    def __init__(self, config):
 | 
						|
        CGAbstractMethod.__init__(self, None, 'Register', 'void',
 | 
						|
                                  [Argument('nsScriptNameSpaceManager*', 'aNameSpaceManager')])
 | 
						|
        self.config = config
 | 
						|
 | 
						|
    def _defineMacro(self):
 | 
						|
       return """
 | 
						|
#define REGISTER_PROTO(_dom_class, _pref_check) \\
 | 
						|
  aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _pref_check);\n\n"""
 | 
						|
    def _undefineMacro(self):
 | 
						|
        return "\n#undef REGISTER_PROTO"
 | 
						|
    def _registerProtos(self):
 | 
						|
        def getPrefCheck(desc):
 | 
						|
            if desc.interface.getExtendedAttribute("PrefControlled") is None:
 | 
						|
                return "nullptr"
 | 
						|
            return "%sBinding::PrefEnabled" % desc.name
 | 
						|
        lines = ["REGISTER_PROTO(%s, %s);" % (desc.name, getPrefCheck(desc))
 | 
						|
                 for desc in self.config.getDescriptors(hasInterfaceObject=True,
 | 
						|
                                                        isExternal=False,
 | 
						|
                                                        workers=False,
 | 
						|
                                                        register=True)]
 | 
						|
        return '\n'.join(lines) + '\n'
 | 
						|
    def definition_body(self):
 | 
						|
        return self._defineMacro() + self._registerProtos() + self._undefineMacro()
 | 
						|
 | 
						|
class CGBindingRoot(CGThing):
 | 
						|
    """
 | 
						|
    Root codegen class for binding generation. Instantiate the class, and call
 | 
						|
    declare or define to generate header or cpp code (respectively).
 | 
						|
    """
 | 
						|
    def __init__(self, config, prefix, webIDLFile):
 | 
						|
        descriptors = config.getDescriptors(webIDLFile=webIDLFile,
 | 
						|
                                            hasInterfaceOrInterfacePrototypeObject=True)
 | 
						|
        dictionaries = config.getDictionaries(webIDLFile)
 | 
						|
 | 
						|
        forwardDeclares = [CGClassForwardDeclare('XPCWrappedNativeScope')]
 | 
						|
 | 
						|
        descriptorsForForwardDeclaration = list(descriptors)
 | 
						|
        for dictionary in dictionaries:
 | 
						|
            curDict = dictionary
 | 
						|
            ifacemembers = []
 | 
						|
            while curDict:
 | 
						|
                ifacemembers.extend([m.type.unroll().inner for m
 | 
						|
                                     in curDict.members
 | 
						|
                                     if m.type.unroll().isInterface()])
 | 
						|
                curDict = curDict.parent
 | 
						|
            # Put in all the non-worker descriptors
 | 
						|
            descriptorsForForwardDeclaration.extend(
 | 
						|
                [config.getDescriptor(iface.identifier.name, False) for
 | 
						|
                 iface in ifacemembers])
 | 
						|
            # And now the worker ones.  But these may not exist, so we
 | 
						|
            # have to be more careful.
 | 
						|
            for iface in ifacemembers:
 | 
						|
                try:
 | 
						|
                    descriptorsForForwardDeclaration.append(
 | 
						|
                        config.getDescriptor(iface.identifier.name, True))
 | 
						|
                except NoSuchDescriptorError:
 | 
						|
                    # just move along
 | 
						|
                    pass
 | 
						|
 | 
						|
        for x in descriptorsForForwardDeclaration:
 | 
						|
            nativeType = x.nativeType
 | 
						|
            components = x.nativeType.split('::')
 | 
						|
            className = components[-1]
 | 
						|
            # JSObject is a struct, not a class
 | 
						|
            declare = CGClassForwardDeclare(className, className is "JSObject")
 | 
						|
            if len(components) > 1:
 | 
						|
                declare = CGNamespace.build(components[:-1],
 | 
						|
                                            CGWrapper(declare, declarePre='\n',
 | 
						|
                                                      declarePost='\n'),
 | 
						|
                                            declareOnly=True)
 | 
						|
            forwardDeclares.append(CGWrapper(declare, declarePost='\n'))
 | 
						|
 | 
						|
        forwardDeclares = CGList(forwardDeclares)
 | 
						|
 | 
						|
        descriptorsWithPrototype = filter(lambda d: d.interface.hasInterfacePrototypeObject(),
 | 
						|
                                          descriptors)
 | 
						|
        traitsClasses = [CGPrototypeTraitsClass(d) for d in descriptorsWithPrototype]
 | 
						|
 | 
						|
        # We must have a 1:1 mapping here, skip for prototypes that have more
 | 
						|
        # than one concrete class implementation.
 | 
						|
        traitsClasses.extend([CGPrototypeIDMapClass(d) for d in descriptorsWithPrototype
 | 
						|
                              if d.uniqueImplementation])
 | 
						|
 | 
						|
        # Wrap all of that in our namespaces.
 | 
						|
        if len(traitsClasses) > 0:
 | 
						|
            traitsClasses = CGNamespace.build(['mozilla', 'dom'],
 | 
						|
                                     CGWrapper(CGList(traitsClasses),
 | 
						|
                                               declarePre='\n'),
 | 
						|
                                               declareOnly=True)
 | 
						|
            traitsClasses = CGWrapper(traitsClasses, declarePost='\n')
 | 
						|
        else:
 | 
						|
            traitsClasses = None
 | 
						|
 | 
						|
        # Do codegen for all the enums
 | 
						|
        def makeEnum(e):
 | 
						|
            return CGNamespace.build([e.identifier.name + "Values"],
 | 
						|
                                     CGEnum(e))
 | 
						|
        def makeEnumTypedef(e):
 | 
						|
            return CGGeneric(declare=("typedef %sValues::valuelist %s;\n" %
 | 
						|
                                      (e.identifier.name, e.identifier.name)))
 | 
						|
        cgthings = [ fun(e) for e in config.getEnums(webIDLFile)
 | 
						|
                     for fun in [makeEnum, makeEnumTypedef] ]
 | 
						|
 | 
						|
        # Do codegen for all the dictionaries.  We have to be a bit careful
 | 
						|
        # here, because we have to generate these in order from least derived
 | 
						|
        # to most derived so that class inheritance works out.  We also have to
 | 
						|
        # generate members before the dictionary that contains them.
 | 
						|
        #
 | 
						|
        # XXXbz this will fail if we have two webidl files A and B such that A
 | 
						|
        # declares a dictionary which inherits from a dictionary in B and B
 | 
						|
        # declares a dictionary (possibly a different one!) that inherits from a
 | 
						|
        # dictionary in A.  The good news is that I expect this to never happen.
 | 
						|
        reSortedDictionaries = []
 | 
						|
        dictionaries = set(dictionaries)
 | 
						|
        while len(dictionaries) != 0:
 | 
						|
            # Find the dictionaries that don't depend on anything else anymore
 | 
						|
            # and move them over.
 | 
						|
            toMove = [d for d in dictionaries if
 | 
						|
                      len(CGDictionary.getDictionaryDependencies(d) &
 | 
						|
                          dictionaries) == 0]
 | 
						|
            if len(toMove) == 0:
 | 
						|
                raise TypeError("Loop in dictionary dependency graph")
 | 
						|
            dictionaries = dictionaries - set(toMove)
 | 
						|
            reSortedDictionaries.extend(toMove)
 | 
						|
 | 
						|
        dictionaries = reSortedDictionaries
 | 
						|
        cgthings.extend([CGDictionary(d, config.getDescriptorProvider(True))
 | 
						|
                         for d in dictionaries])
 | 
						|
        cgthings.extend([CGDictionary(d, config.getDescriptorProvider(False))
 | 
						|
                         for d in dictionaries])
 | 
						|
 | 
						|
        # Do codegen for all the descriptors
 | 
						|
        cgthings.extend([CGDescriptor(x) for x in descriptors])
 | 
						|
 | 
						|
        # And make sure we have the right number of newlines at the end
 | 
						|
        curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
 | 
						|
 | 
						|
        # Wrap all of that in our namespaces.
 | 
						|
        curr = CGNamespace.build(['mozilla', 'dom'],
 | 
						|
                                 CGWrapper(curr, pre="\n"))
 | 
						|
 | 
						|
        curr = CGList([forwardDeclares,
 | 
						|
                       CGWrapper(CGGeneric("using namespace mozilla::dom;"),
 | 
						|
                                 defineOnly=True),
 | 
						|
                       traitsClasses, curr],
 | 
						|
                      "\n")
 | 
						|
 | 
						|
        # Add header includes.
 | 
						|
        curr = CGHeaders(descriptors,
 | 
						|
                         dictionaries,
 | 
						|
                         ['mozilla/dom/BindingUtils.h',
 | 
						|
                          'mozilla/dom/DOMJSClass.h',
 | 
						|
                          'mozilla/dom/DOMJSProxyHandler.h'],
 | 
						|
                         ['mozilla/dom/Nullable.h',
 | 
						|
                          'PrimitiveConversions.h',
 | 
						|
                          'XPCQuickStubs.h',
 | 
						|
                          'nsDOMQS.h',
 | 
						|
                          'AccessCheck.h',
 | 
						|
                          'WorkerPrivate.h',
 | 
						|
                          'nsContentUtils.h',
 | 
						|
                          'mozilla/Preferences.h',
 | 
						|
                          # Have to include nsDOMQS.h to get fast arg unwrapping
 | 
						|
                          # for old-binding things with castability.
 | 
						|
                          'nsDOMQS.h'
 | 
						|
                          ],
 | 
						|
                         curr)
 | 
						|
 | 
						|
        # Add include guards.
 | 
						|
        curr = CGIncludeGuard(prefix, curr)
 | 
						|
 | 
						|
        # Add the auto-generated comment.
 | 
						|
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
 | 
						|
 | 
						|
        # Store the final result.
 | 
						|
        self.root = curr
 | 
						|
 | 
						|
    def declare(self):
 | 
						|
        return stripTrailingWhitespace(self.root.declare())
 | 
						|
    def define(self):
 | 
						|
        return stripTrailingWhitespace(self.root.define())
 | 
						|
 | 
						|
 | 
						|
class GlobalGenRoots():
 | 
						|
    """
 | 
						|
    Roots for global codegen.
 | 
						|
 | 
						|
    To generate code, call the method associated with the target, and then
 | 
						|
    call the appropriate define/declare method.
 | 
						|
    """
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def PrototypeList(config):
 | 
						|
 | 
						|
        # Prototype ID enum.
 | 
						|
        protos = [d.name for d in config.getDescriptors(hasInterfacePrototypeObject=True)]
 | 
						|
        idEnum = CGNamespacedEnum('id', 'ID', protos, [0])
 | 
						|
        idEnum = CGList([idEnum])
 | 
						|
        idEnum.append(CGGeneric(declare="const unsigned MaxProtoChainLength = " +
 | 
						|
                                str(config.maxProtoChainLength) + ";\n\n"))
 | 
						|
 | 
						|
        # Wrap all of that in our namespaces.
 | 
						|
        idEnum = CGNamespace.build(['mozilla', 'dom', 'prototypes'],
 | 
						|
                                   CGWrapper(idEnum, pre='\n'))
 | 
						|
        idEnum = CGWrapper(idEnum, post='\n')
 | 
						|
 | 
						|
        curr = CGList([idEnum])
 | 
						|
 | 
						|
        # Constructor ID enum.
 | 
						|
        constructors = [d.name for d in config.getDescriptors(hasInterfaceObject=True,
 | 
						|
                                                              hasInterfacePrototypeObject=False)]
 | 
						|
        idEnum = CGNamespacedEnum('id', 'ID', constructors, [0])
 | 
						|
 | 
						|
        # Wrap all of that in our namespaces.
 | 
						|
        idEnum = CGNamespace.build(['mozilla', 'dom', 'constructors'],
 | 
						|
                                   CGWrapper(idEnum, pre='\n'))
 | 
						|
        idEnum = CGWrapper(idEnum, post='\n')
 | 
						|
 | 
						|
        curr.append(idEnum)
 | 
						|
 | 
						|
        traitsDecl = CGGeneric(declare="""
 | 
						|
template <prototypes::ID PrototypeID>
 | 
						|
struct PrototypeTraits;
 | 
						|
 | 
						|
template <class ConcreteClass>
 | 
						|
struct PrototypeIDMap;
 | 
						|
""")
 | 
						|
 | 
						|
        traitsDecl = CGNamespace.build(['mozilla', 'dom'],
 | 
						|
                                        CGWrapper(traitsDecl, post='\n'))
 | 
						|
 | 
						|
        curr.append(traitsDecl)
 | 
						|
 | 
						|
        # Add include guards.
 | 
						|
        curr = CGIncludeGuard('PrototypeList', curr)
 | 
						|
 | 
						|
        # Add the auto-generated comment.
 | 
						|
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
 | 
						|
 | 
						|
        # Done.
 | 
						|
        return curr
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def RegisterBindings(config):
 | 
						|
 | 
						|
        # TODO - Generate the methods we want
 | 
						|
        curr = CGRegisterProtos(config)
 | 
						|
 | 
						|
        # Wrap all of that in our namespaces.
 | 
						|
        curr = CGNamespace.build(['mozilla', 'dom'],
 | 
						|
                                 CGWrapper(curr, post='\n'))
 | 
						|
        curr = CGWrapper(curr, post='\n')
 | 
						|
 | 
						|
        # Add the includes
 | 
						|
        defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
 | 
						|
                          for desc in config.getDescriptors(hasInterfaceObject=True,
 | 
						|
                                                            workers=False,
 | 
						|
                                                            register=True)]
 | 
						|
        defineIncludes.append('nsScriptNameSpaceManager.h')
 | 
						|
        curr = CGHeaders([], [], [], defineIncludes, curr)
 | 
						|
 | 
						|
        # Add include guards.
 | 
						|
        curr = CGIncludeGuard('RegisterBindings', curr)
 | 
						|
 | 
						|
        # Done.
 | 
						|
        return curr
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def UnionTypes(config):
 | 
						|
 | 
						|
        (includes, declarations, unions) = UnionTypes(config.getDescriptors())
 | 
						|
        includes.add("mozilla/dom/BindingUtils.h")
 | 
						|
 | 
						|
        # Wrap all of that in our namespaces.
 | 
						|
        curr = CGNamespace.build(['mozilla', 'dom'], unions)
 | 
						|
 | 
						|
        curr = CGWrapper(curr, post='\n')
 | 
						|
 | 
						|
        namespaces = []
 | 
						|
        stack = [CGList([])]
 | 
						|
        for (clazz, isStruct) in SortedTuples(declarations):
 | 
						|
            elements = clazz.split("::")
 | 
						|
            clazz = CGClassForwardDeclare(elements.pop(), isStruct=isStruct)
 | 
						|
            i = 0
 | 
						|
            if len(elements) > 0:
 | 
						|
                common = min(len(namespaces), len(elements))
 | 
						|
                while i < common and namespaces[i] == elements[i]:
 | 
						|
                    i += 1
 | 
						|
 | 
						|
            # pop all the namespaces that should be closed
 | 
						|
            namespaces = namespaces[:i]
 | 
						|
 | 
						|
            # add all the namespaces that should be opened
 | 
						|
            for j, namespace in enumerate(elements[i:]):
 | 
						|
                namespaces.append(namespace)
 | 
						|
                # every CGNamespace that we add holds a CGList
 | 
						|
                list = CGList([])
 | 
						|
                # add the new namespace to the list on top of the stack
 | 
						|
                stack[i + j].append(CGNamespace(namespace, list))
 | 
						|
                # set the top of the namespace stack to the list of the new
 | 
						|
                # namespace
 | 
						|
                stack[i + j + 1:] = [list]
 | 
						|
 | 
						|
            stack[len(elements)].append(clazz)
 | 
						|
 | 
						|
        curr = CGList([stack[0], curr], "\n")
 | 
						|
 | 
						|
        curr = CGHeaders([], [], includes, [], curr)
 | 
						|
 | 
						|
        # Add include guards.
 | 
						|
        curr = CGIncludeGuard('UnionTypes', curr)
 | 
						|
 | 
						|
        # Done.
 | 
						|
        return curr
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def UnionConversions(config):
 | 
						|
 | 
						|
        unions = UnionConversions(config.getDescriptors())
 | 
						|
 | 
						|
        # Wrap all of that in our namespaces.
 | 
						|
        curr = CGNamespace.build(['mozilla', 'dom'], unions)
 | 
						|
 | 
						|
        curr = CGWrapper(curr, post='\n')
 | 
						|
 | 
						|
        curr = CGHeaders([], [], ["nsDebug.h", "mozilla/dom/UnionTypes.h", "nsDOMQS.h"], [], curr)
 | 
						|
 | 
						|
        # Add include guards.
 | 
						|
        curr = CGIncludeGuard('UnionConversions', curr)
 | 
						|
 | 
						|
        # Done.
 | 
						|
        return curr
 |