summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.md7
-rw-r--r--COPYRIGHT.txt5
-rw-r--r--DONORS.md141
-rw-r--r--SConstruct40
-rw-r--r--core/bind/core_bind.cpp4
-rw-r--r--core/class_db.cpp12
-rw-r--r--core/class_db.h23
-rw-r--r--core/color.cpp12
-rw-r--r--core/color.h4
-rw-r--r--core/hash_map.h90
-rw-r--r--core/helper/math_fieldwise.cpp2
-rw-r--r--core/helper/math_fieldwise.h2
-rw-r--r--core/image.cpp6
-rw-r--r--core/io/file_access_compressed.h10
-rw-r--r--core/io/file_access_encrypted.cpp4
-rw-r--r--core/io/file_access_encrypted.h2
-rw-r--r--core/io/file_access_network.cpp4
-rw-r--r--core/io/file_access_network.h4
-rw-r--r--core/io/marshalls.cpp10
-rw-r--r--core/io/resource_format_binary.cpp18
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/resource_import.cpp26
-rw-r--r--core/io/resource_import.h3
-rw-r--r--core/io/resource_loader.cpp107
-rw-r--r--core/io/resource_loader.h8
-rw-r--r--core/io/translation_loader_po.cpp4
-rw-r--r--core/io/xml_parser.cpp2
-rw-r--r--core/io/xml_parser.h2
-rw-r--r--core/list.h4
-rw-r--r--core/math/a_star.h2
-rw-r--r--core/math/face3.cpp2
-rw-r--r--core/math/matrix3.cpp83
-rw-r--r--core/math/matrix3.h7
-rw-r--r--core/math/quick_hull.cpp10
-rw-r--r--core/math/transform.cpp12
-rw-r--r--core/method_bind.h3
-rw-r--r--core/object.cpp59
-rw-r--r--core/object.h6
-rw-r--r--core/ordered_hash_map.h315
-rw-r--r--core/os/os.cpp3
-rw-r--r--core/packed_data_container.cpp8
-rw-r--r--core/pair.h10
-rw-r--r--core/pool_allocator.cpp6
-rw-r--r--core/project_settings.cpp2
-rw-r--r--core/project_settings.h2
-rw-r--r--core/reference.h2
-rw-r--r--core/script_language.cpp5
-rw-r--r--core/script_language.h1
-rw-r--r--core/type_info.h53
-rw-r--r--core/ustring.cpp22
-rw-r--r--core/variant_call.cpp6
-rw-r--r--core/vmap.h6
-rw-r--r--core/vset.h7
-rw-r--r--doc/base/classes.xml10046
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp19
-rw-r--r--drivers/alsa/audio_driver_alsa.h1
-rw-r--r--drivers/convex_decomp/b2d_decompose.cpp2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp13
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp37
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h52
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp20
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp10
-rw-r--r--drivers/gles3/shaders/canvas.glsl24
-rw-r--r--drivers/gles3/shaders/scene.glsl54
-rw-r--r--drivers/gles3/shaders/ssao_blur.glsl7
-rw-r--r--drivers/png/image_loader_png.cpp4
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp44
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h1
-rw-r--r--drivers/rtaudio/audio_driver_rtaudio.cpp13
-rw-r--r--drivers/unix/packet_peer_udp_posix.cpp4
-rw-r--r--drivers/unix/tcp_server_posix.cpp2
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp35
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h3
-rw-r--r--editor/SCsub60
-rw-r--r--editor/code_editor.cpp22
-rw-r--r--editor/doc/doc_data.cpp133
-rw-r--r--editor/editor_about.cpp88
-rw-r--r--editor/editor_about.h1
-rw-r--r--editor/editor_audio_buses.cpp5
-rw-r--r--editor/editor_data.cpp2
-rw-r--r--editor/editor_data.h2
-rw-r--r--editor/editor_dir_dialog.cpp120
-rw-r--r--editor/editor_dir_dialog.h7
-rw-r--r--editor/editor_export.cpp2
-rw-r--r--editor/editor_export.h2
-rw-r--r--editor/editor_file_dialog.cpp18
-rw-r--r--editor/editor_file_system.cpp58
-rw-r--r--editor/editor_file_system.h3
-rw-r--r--editor/editor_fonts.cpp81
-rw-r--r--editor/editor_help.cpp32
-rw-r--r--editor/editor_node.cpp314
-rw-r--r--editor/editor_node.h8
-rw-r--r--editor/editor_path.cpp2
-rw-r--r--editor/editor_plugin.cpp10
-rw-r--r--editor/editor_resource_preview.cpp4
-rw-r--r--editor/editor_settings.cpp8
-rw-r--r--editor/editor_themes.cpp342
-rw-r--r--editor/export_template_manager.h2
-rw-r--r--editor/filesystem_dock.cpp70
-rw-r--r--editor/filesystem_dock.h1
-rw-r--r--editor/icons/SCsub37
-rw-r--r--editor/icons/dark/icon_2_d.svg5
-rw-r--r--editor/icons/dark/icon_3_d.svg5
-rw-r--r--editor/icons/dark/icon_GUI_checked.svg5
-rw-r--r--editor/icons/dark/icon_GUI_dropdown.svg7
-rw-r--r--editor/icons/dark/icon_GUI_hslider_bg.svg5
-rw-r--r--editor/icons/dark/icon_GUI_hsplitter.svg5
-rw-r--r--editor/icons/dark/icon_GUI_mini_tab_menu.svg7
-rw-r--r--editor/icons/dark/icon_GUI_option_arrow.svg5
-rw-r--r--editor/icons/dark/icon_GUI_play_button_group.svg5
-rw-r--r--editor/icons/dark/icon_GUI_progress_bar.svg5
-rw-r--r--editor/icons/dark/icon_GUI_progress_fill.svg5
-rw-r--r--editor/icons/dark/icon_GUI_radio_checked.svg6
-rw-r--r--editor/icons/dark/icon_GUI_radio_unchecked.svg5
-rw-r--r--editor/icons/dark/icon_GUI_scroll_bg.svg1
-rw-r--r--editor/icons/dark/icon_GUI_scroll_grabber.svg5
-rw-r--r--editor/icons/dark/icon_GUI_scroll_grabber_hl.svg5
-rw-r--r--editor/icons/dark/icon_GUI_scroll_grabber_pressed.svg5
-rw-r--r--editor/icons/dark/icon_GUI_slider_grabber.svg5
-rw-r--r--editor/icons/dark/icon_GUI_slider_grabber_hl.svg6
-rw-r--r--editor/icons/dark/icon_GUI_spinbox_updown.svg5
-rw-r--r--editor/icons/dark/icon_GUI_tab_menu.svg7
-rw-r--r--editor/icons/dark/icon_GUI_toggle_off.svg5
-rw-r--r--editor/icons/dark/icon_GUI_toggle_on.svg5
-rw-r--r--editor/icons/dark/icon_GUI_tree_arrow_down.svg5
-rw-r--r--editor/icons/dark/icon_GUI_tree_arrow_right.svg5
-rw-r--r--editor/icons/dark/icon_GUI_unchecked.svg5
-rw-r--r--editor/icons/dark/icon_GUI_vslider_bg.svg5
-rw-r--r--editor/icons/dark/icon_GUI_vsplit_bg.svg5
-rw-r--r--editor/icons/dark/icon_GUI_vsplitter.svg5
-rw-r--r--editor/icons/dark/icon_accept_dialog.svg5
-rw-r--r--editor/icons/dark/icon_add.svg5
-rw-r--r--editor/icons/dark/icon_anchor.svg5
-rw-r--r--editor/icons/dark/icon_animated_sprite.svg7
-rw-r--r--editor/icons/dark/icon_animated_sprite_3d.svg7
-rw-r--r--editor/icons/dark/icon_animation.svg5
-rw-r--r--editor/icons/dark/icon_animation_player.svg5
-rw-r--r--editor/icons/dark/icon_animation_tree_player.svg5
-rw-r--r--editor/icons/dark/icon_area.svg5
-rw-r--r--editor/icons/dark/icon_area_2d.svg5
-rw-r--r--editor/icons/dark/icon_arrow_left.svg5
-rw-r--r--editor/icons/dark/icon_arrow_right.svg5
-rw-r--r--editor/icons/dark/icon_arrow_up.svg5
-rw-r--r--editor/icons/dark/icon_asset_lib.svg5
-rw-r--r--editor/icons/dark/icon_atlas_texture.svg5
-rw-r--r--editor/icons/dark/icon_audio_bus_bypass.svg5
-rw-r--r--editor/icons/dark/icon_audio_bus_layout.svg12
-rw-r--r--editor/icons/dark/icon_audio_bus_mute.svg5
-rw-r--r--editor/icons/dark/icon_audio_bus_solo.svg5
-rw-r--r--editor/icons/dark/icon_audio_effect_amplify.svg12
-rw-r--r--editor/icons/dark/icon_audio_stream_gibberish.svg5
-rw-r--r--editor/icons/dark/icon_audio_stream_player.svg13
-rw-r--r--editor/icons/dark/icon_audio_stream_player_2_d.svg13
-rw-r--r--editor/icons/dark/icon_audio_stream_player_3_d.svg13
-rw-r--r--editor/icons/dark/icon_audio_stream_sample.svg12
-rw-r--r--editor/icons/dark/icon_auto_play.svg5
-rw-r--r--editor/icons/dark/icon_back.svg5
-rw-r--r--editor/icons/dark/icon_back_buffer_copy.svg5
-rw-r--r--editor/icons/dark/icon_bake.svg5
-rw-r--r--editor/icons/dark/icon_baked_light.svg5
-rw-r--r--editor/icons/dark/icon_baked_light_instance.svg5
-rw-r--r--editor/icons/dark/icon_baked_light_sampler.svg5
-rw-r--r--editor/icons/dark/icon_bit_map.svg5
-rw-r--r--editor/icons/dark/icon_bitmap_font.svg5
-rw-r--r--editor/icons/dark/icon_blend.svg5
-rw-r--r--editor/icons/dark/icon_bone.svg5
-rw-r--r--editor/icons/dark/icon_bone_attachment.svg5
-rw-r--r--editor/icons/dark/icon_bone_track.svg5
-rw-r--r--editor/icons/dark/icon_bool.svg5
-rw-r--r--editor/icons/dark/icon_box_shape.svg7
-rw-r--r--editor/icons/dark/icon_bus_vu_db.svg12
-rw-r--r--editor/icons/dark/icon_bus_vu_empty.svg13
-rw-r--r--editor/icons/dark/icon_bus_vu_frozen.svg12
-rw-r--r--editor/icons/dark/icon_bus_vu_full.svg12
-rw-r--r--editor/icons/dark/icon_button.svg5
-rw-r--r--editor/icons/dark/icon_button_group.svg5
-rw-r--r--editor/icons/dark/icon_camera.svg5
-rw-r--r--editor/icons/dark/icon_camera_2d.svg5
-rw-r--r--editor/icons/dark/icon_canvas_item.svg5
-rw-r--r--editor/icons/dark/icon_canvas_item_material.svg11
-rw-r--r--editor/icons/dark/icon_canvas_item_shader.svg11
-rw-r--r--editor/icons/dark/icon_canvas_item_shader_graph.svg19
-rw-r--r--editor/icons/dark/icon_canvas_layer.svg5
-rw-r--r--editor/icons/dark/icon_canvas_modulate.svg8
-rw-r--r--editor/icons/dark/icon_capsule_mesh.svg5
-rw-r--r--editor/icons/dark/icon_capsule_shape.svg6
-rw-r--r--editor/icons/dark/icon_capsule_shape_2d.svg5
-rw-r--r--editor/icons/dark/icon_center_container.svg5
-rw-r--r--editor/icons/dark/icon_check_box.svg5
-rw-r--r--editor/icons/dark/icon_check_button.svg5
-rw-r--r--editor/icons/dark/icon_checkerboard.svg6
-rw-r--r--editor/icons/dark/icon_circle_shape_2d.svg5
-rw-r--r--editor/icons/dark/icon_class_list.svg11
-rw-r--r--editor/icons/dark/icon_close.svg5
-rw-r--r--editor/icons/dark/icon_collapse.svg5
-rw-r--r--editor/icons/dark/icon_collision_2d.svg5
-rw-r--r--editor/icons/dark/icon_collision_polygon.svg5
-rw-r--r--editor/icons/dark/icon_collision_shape.svg7
-rw-r--r--editor/icons/dark/icon_collision_shape_2d.svg5
-rw-r--r--editor/icons/dark/icon_color.svg24
-rw-r--r--editor/icons/dark/icon_color_pick.svg5
-rw-r--r--editor/icons/dark/icon_color_picker.svg5
-rw-r--r--editor/icons/dark/icon_color_picker_button.svg7
-rw-r--r--editor/icons/dark/icon_color_ramp.svg11
-rw-r--r--editor/icons/dark/icon_color_rect.svg11
-rw-r--r--editor/icons/dark/icon_concave_polygon_shape.svg12
-rw-r--r--editor/icons/dark/icon_concave_polygon_shape_2d.svg5
-rw-r--r--editor/icons/dark/icon_cone_twist_joint.svg7
-rw-r--r--editor/icons/dark/icon_confirmation_dialog.svg5
-rw-r--r--editor/icons/dark/icon_connect.svg7
-rw-r--r--editor/icons/dark/icon_connection_and_groups.svg5
-rw-r--r--editor/icons/dark/icon_container.svg5
-rw-r--r--editor/icons/dark/icon_control.svg5
-rw-r--r--editor/icons/dark/icon_control_align_bottom_center.svg7
-rw-r--r--editor/icons/dark/icon_control_align_bottom_left.svg7
-rw-r--r--editor/icons/dark/icon_control_align_bottom_right.svg7
-rw-r--r--editor/icons/dark/icon_control_align_bottom_wide.svg7
-rw-r--r--editor/icons/dark/icon_control_align_center.svg7
-rw-r--r--editor/icons/dark/icon_control_align_center_left.svg5
-rw-r--r--editor/icons/dark/icon_control_align_center_right.svg5
-rw-r--r--editor/icons/dark/icon_control_align_left_center.svg7
-rw-r--r--editor/icons/dark/icon_control_align_left_wide.svg7
-rw-r--r--editor/icons/dark/icon_control_align_right_center.svg7
-rw-r--r--editor/icons/dark/icon_control_align_right_wide.svg7
-rw-r--r--editor/icons/dark/icon_control_align_top_center.svg7
-rw-r--r--editor/icons/dark/icon_control_align_top_left.svg7
-rw-r--r--editor/icons/dark/icon_control_align_top_right.svg7
-rw-r--r--editor/icons/dark/icon_control_align_top_wide.svg7
-rw-r--r--editor/icons/dark/icon_control_align_wide.svg7
-rw-r--r--editor/icons/dark/icon_control_hcenter_wide.svg7
-rw-r--r--editor/icons/dark/icon_control_vcenter_wide.svg7
-rw-r--r--editor/icons/dark/icon_convex_polygon_shape.svg9
-rw-r--r--editor/icons/dark/icon_convex_polygon_shape_2d.svg5
-rw-r--r--editor/icons/dark/icon_copy_node_path.svg6
-rw-r--r--editor/icons/dark/icon_create_new_scene_from.svg8
-rw-r--r--editor/icons/dark/icon_cube_map.svg10
-rw-r--r--editor/icons/dark/icon_cube_mesh.svg5
-rw-r--r--editor/icons/dark/icon_curve.svg6
-rw-r--r--editor/icons/dark/icon_curve_2d.svg5
-rw-r--r--editor/icons/dark/icon_curve_3d.svg5
-rw-r--r--editor/icons/dark/icon_curve_close.svg11
-rw-r--r--editor/icons/dark/icon_curve_constant.svg5
-rw-r--r--editor/icons/dark/icon_curve_create.svg10
-rw-r--r--editor/icons/dark/icon_curve_curve.svg9
-rw-r--r--editor/icons/dark/icon_curve_delete.svg9
-rw-r--r--editor/icons/dark/icon_curve_edit.svg9
-rw-r--r--editor/icons/dark/icon_curve_in.svg5
-rw-r--r--editor/icons/dark/icon_curve_in_out.svg5
-rw-r--r--editor/icons/dark/icon_curve_linear.svg5
-rw-r--r--editor/icons/dark/icon_curve_out.svg5
-rw-r--r--editor/icons/dark/icon_curve_out_in.svg5
-rw-r--r--editor/icons/dark/icon_curve_texture.svg5
-rw-r--r--editor/icons/dark/icon_cylinder_mesh.svg5
-rw-r--r--editor/icons/dark/icon_damped_spring_joint_2d.svg6
-rw-r--r--editor/icons/dark/icon_debug.svg14
-rw-r--r--editor/icons/dark/icon_debug_continue.svg9
-rw-r--r--editor/icons/dark/icon_debug_next.svg12
-rw-r--r--editor/icons/dark/icon_debug_step.svg13
-rw-r--r--editor/icons/dark/icon_default_project_icon.svg33
-rw-r--r--editor/icons/dark/icon_dependency_changed.svg6
-rw-r--r--editor/icons/dark/icon_dependency_changed_hl.svg5
-rw-r--r--editor/icons/dark/icon_dependency_local_changed.svg6
-rw-r--r--editor/icons/dark/icon_dependency_local_changed_hl.svg5
-rw-r--r--editor/icons/dark/icon_dependency_ok.svg6
-rw-r--r--editor/icons/dark/icon_dependency_ok_hl.svg5
-rw-r--r--editor/icons/dark/icon_directional_light.svg5
-rw-r--r--editor/icons/dark/icon_distraction_free.svg9
-rw-r--r--editor/icons/dark/icon_duplicate.svg5
-rw-r--r--editor/icons/dark/icon_dynamic_font.svg6
-rw-r--r--editor/icons/dark/icon_dynamic_font_data.svg6
-rw-r--r--editor/icons/dark/icon_edit.svg5
-rw-r--r--editor/icons/dark/icon_edit_key.svg6
-rw-r--r--editor/icons/dark/icon_edit_pivot.svg5
-rw-r--r--editor/icons/dark/icon_edit_resource.svg5
-rw-r--r--editor/icons/dark/icon_editor_3d_handle.svg6
-rw-r--r--editor/icons/dark/icon_editor_control_anchor.svg8
-rw-r--r--editor/icons/dark/icon_editor_handle.svg6
-rw-r--r--editor/icons/dark/icon_editor_pivot.svg6
-rw-r--r--editor/icons/dark/icon_editor_plugin.svg9
-rw-r--r--editor/icons/dark/icon_environment.svg8
-rw-r--r--editor/icons/dark/icon_error.svg5
-rw-r--r--editor/icons/dark/icon_error_sign.svg7
-rw-r--r--editor/icons/dark/icon_event_player.svg8
-rw-r--r--editor/icons/dark/icon_favorites.svg5
-rw-r--r--editor/icons/dark/icon_file_big.svg7
-rw-r--r--editor/icons/dark/icon_file_dialog.svg5
-rw-r--r--editor/icons/dark/icon_file_list.svg5
-rw-r--r--editor/icons/dark/icon_file_server.svg7
-rw-r--r--editor/icons/dark/icon_file_server_active.svg7
-rw-r--r--editor/icons/dark/icon_file_thumbnail.svg5
-rw-r--r--editor/icons/dark/icon_fixed_material.svg5
-rw-r--r--editor/icons/dark/icon_fixed_spatial_material.svg11
-rw-r--r--editor/icons/dark/icon_folder.svg5
-rw-r--r--editor/icons/dark/icon_folder_big.svg5
-rw-r--r--editor/icons/dark/icon_font.svg13
-rw-r--r--editor/icons/dark/icon_forward.svg5
-rw-r--r--editor/icons/dark/icon_g_d_native_library.svg5
-rw-r--r--editor/icons/dark/icon_g_d_script.svg5
-rw-r--r--editor/icons/dark/icon_g_i_probe.svg5
-rw-r--r--editor/icons/dark/icon_g_i_probe_data.svg5
-rw-r--r--editor/icons/dark/icon_generic_6_d_o_f_joint.svg5
-rw-r--r--editor/icons/dark/icon_gizmo_directional_light.svg5
-rw-r--r--editor/icons/dark/icon_gizmo_light.svg5
-rw-r--r--editor/icons/dark/icon_gizmo_listener.svg7
-rw-r--r--editor/icons/dark/icon_gizmo_spatial_sample_player.svg5
-rw-r--r--editor/icons/dark/icon_gizmo_spatial_stream_player.svg5
-rw-r--r--editor/icons/dark/icon_godot.svg33
-rw-r--r--editor/icons/dark/icon_gradient.svg11
-rw-r--r--editor/icons/dark/icon_gradient_texture.svg19
-rw-r--r--editor/icons/dark/icon_graph_comment.svg5
-rw-r--r--editor/icons/dark/icon_graph_cube_uniform.svg5
-rw-r--r--editor/icons/dark/icon_graph_curve_map.svg6
-rw-r--r--editor/icons/dark/icon_graph_default_texture.svg5
-rw-r--r--editor/icons/dark/icon_graph_edit.svg6
-rw-r--r--editor/icons/dark/icon_graph_input.svg5
-rw-r--r--editor/icons/dark/icon_graph_node.svg6
-rw-r--r--editor/icons/dark/icon_graph_rgb.svg12
-rw-r--r--editor/icons/dark/icon_graph_rgb_op.svg11
-rw-r--r--editor/icons/dark/icon_graph_rgb_uniform.svg12
-rw-r--r--editor/icons/dark/icon_graph_scalar.svg5
-rw-r--r--editor/icons/dark/icon_graph_scalar_interp.svg5
-rw-r--r--editor/icons/dark/icon_graph_scalar_op.svg8
-rw-r--r--editor/icons/dark/icon_graph_scalar_uniform.svg5
-rw-r--r--editor/icons/dark/icon_graph_scalars_to_vec.svg11
-rw-r--r--editor/icons/dark/icon_graph_texscreen.svg6
-rw-r--r--editor/icons/dark/icon_graph_texture_uniform.svg5
-rw-r--r--editor/icons/dark/icon_graph_time.svg7
-rw-r--r--editor/icons/dark/icon_graph_vec_dp.svg7
-rw-r--r--editor/icons/dark/icon_graph_vec_interp.svg5
-rw-r--r--editor/icons/dark/icon_graph_vec_length.svg7
-rw-r--r--editor/icons/dark/icon_graph_vec_op.svg5
-rw-r--r--editor/icons/dark/icon_graph_vec_scalar_op.svg6
-rw-r--r--editor/icons/dark/icon_graph_vec_to_scalars.svg11
-rw-r--r--editor/icons/dark/icon_graph_vecs_to_xform.svg11
-rw-r--r--editor/icons/dark/icon_graph_vector.svg5
-rw-r--r--editor/icons/dark/icon_graph_vector_uniform.svg6
-rw-r--r--editor/icons/dark/icon_graph_xform.svg11
-rw-r--r--editor/icons/dark/icon_graph_xform_mult.svg7
-rw-r--r--editor/icons/dark/icon_graph_xform_scalar_func.svg10
-rw-r--r--editor/icons/dark/icon_graph_xform_to_vecs.svg11
-rw-r--r--editor/icons/dark/icon_graph_xform_uniform.svg5
-rw-r--r--editor/icons/dark/icon_graph_xform_vec_func.svg10
-rw-r--r--editor/icons/dark/icon_graph_xform_vec_imult.svg7
-rw-r--r--editor/icons/dark/icon_graph_xform_vec_mult.svg7
-rw-r--r--editor/icons/dark/icon_grid.svg5
-rw-r--r--editor/icons/dark/icon_grid_container.svg5
-rw-r--r--editor/icons/dark/icon_grid_map.svg5
-rw-r--r--editor/icons/dark/icon_groove_joint_2d.svg5
-rw-r--r--editor/icons/dark/icon_group.svg6
-rw-r--r--editor/icons/dark/icon_groups.svg7
-rw-r--r--editor/icons/dark/icon_gui_close.svg5
-rw-r--r--editor/icons/dark/icon_h_box_container.svg7
-rw-r--r--editor/icons/dark/icon_h_button_array.svg5
-rw-r--r--editor/icons/dark/icon_h_scroll_bar.svg5
-rw-r--r--editor/icons/dark/icon_h_separator.svg7
-rw-r--r--editor/icons/dark/icon_h_slider.svg5
-rw-r--r--editor/icons/dark/icon_h_split_container.svg8
-rw-r--r--editor/icons/dark/icon_h_t_t_p_request.svg6
-rw-r--r--editor/icons/dark/icon_headphones.svg11
-rw-r--r--editor/icons/dark/icon_help.svg5
-rw-r--r--editor/icons/dark/icon_help_search.svg7
-rw-r--r--editor/icons/dark/icon_hidden.svg5
-rw-r--r--editor/icons/dark/icon_hinge_joint.svg5
-rw-r--r--editor/icons/dark/icon_history.svg8
-rw-r--r--editor/icons/dark/icon_hsize.svg5
-rw-r--r--editor/icons/dark/icon_image.svg5
-rw-r--r--editor/icons/dark/icon_image_texture.svg5
-rw-r--r--editor/icons/dark/icon_immediate_geometry.svg5
-rw-r--r--editor/icons/dark/icon_import_check.svg5
-rw-r--r--editor/icons/dark/icon_import_fail.svg5
-rw-r--r--editor/icons/dark/icon_instance.svg6
-rw-r--r--editor/icons/dark/icon_instance_options.svg6
-rw-r--r--editor/icons/dark/icon_integer.svg7
-rw-r--r--editor/icons/dark/icon_interp_cubic.svg5
-rw-r--r--editor/icons/dark/icon_interp_linear.svg5
-rw-r--r--editor/icons/dark/icon_interp_raw.svg5
-rw-r--r--editor/icons/dark/icon_interp_wrap_clamp.svg9
-rw-r--r--editor/icons/dark/icon_interp_wrap_loop.svg10
-rw-r--r--editor/icons/dark/icon_interpolated_camera.svg5
-rw-r--r--editor/icons/dark/icon_invalid_key.svg5
-rw-r--r--editor/icons/dark/icon_inverse_kinematics.svg12
-rw-r--r--editor/icons/dark/icon_item_list.svg14
-rw-r--r--editor/icons/dark/icon_joy_axis.svg7
-rw-r--r--editor/icons/dark/icon_joy_button.svg6
-rw-r--r--editor/icons/dark/icon_joypad.svg5
-rw-r--r--editor/icons/dark/icon_key.svg7
-rw-r--r--editor/icons/dark/icon_key_hover.svg5
-rw-r--r--editor/icons/dark/icon_key_invalid.svg5
-rw-r--r--editor/icons/dark/icon_key_next.svg6
-rw-r--r--editor/icons/dark/icon_key_selected.svg5
-rw-r--r--editor/icons/dark/icon_key_value.svg5
-rw-r--r--editor/icons/dark/icon_key_xform.svg5
-rw-r--r--editor/icons/dark/icon_keyboard.svg7
-rw-r--r--editor/icons/dark/icon_kinematic_body.svg5
-rw-r--r--editor/icons/dark/icon_kinematic_body_2d.svg5
-rw-r--r--editor/icons/dark/icon_label.svg5
-rw-r--r--editor/icons/dark/icon_large_texture.svg5
-rw-r--r--editor/icons/dark/icon_light_2d.svg5
-rw-r--r--editor/icons/dark/icon_light_occluder_2d.svg11
-rw-r--r--editor/icons/dark/icon_line_2d.svg5
-rw-r--r--editor/icons/dark/icon_line_edit.svg6
-rw-r--r--editor/icons/dark/icon_line_shape_2d.svg7
-rw-r--r--editor/icons/dark/icon_link_button.svg6
-rw-r--r--editor/icons/dark/icon_list_select.svg6
-rw-r--r--editor/icons/dark/icon_listener.svg8
-rw-r--r--editor/icons/dark/icon_load.svg5
-rw-r--r--editor/icons/dark/icon_lock.svg8
-rw-r--r--editor/icons/dark/icon_loop.svg5
-rw-r--r--editor/icons/dark/icon_loop_interpolation.svg10
-rw-r--r--editor/icons/dark/icon_main_play.svg5
-rw-r--r--editor/icons/dark/icon_margin_container.svg6
-rw-r--r--editor/icons/dark/icon_material_preview_cube.svg8
-rw-r--r--editor/icons/dark/icon_material_preview_cube_off.svg9
-rw-r--r--editor/icons/dark/icon_material_preview_light_1.svg5
-rw-r--r--editor/icons/dark/icon_material_preview_light_1_off.svg5
-rw-r--r--editor/icons/dark/icon_material_preview_light_2.svg5
-rw-r--r--editor/icons/dark/icon_material_preview_light_2_off.svg6
-rw-r--r--editor/icons/dark/icon_material_preview_sphere.svg5
-rw-r--r--editor/icons/dark/icon_material_preview_sphere_off.svg5
-rw-r--r--editor/icons/dark/icon_matrix.svg19
-rw-r--r--editor/icons/dark/icon_menu_button.svg6
-rw-r--r--editor/icons/dark/icon_mesh.svg5
-rw-r--r--editor/icons/dark/icon_mesh_instance.svg13
-rw-r--r--editor/icons/dark/icon_mesh_library.svg5
-rw-r--r--editor/icons/dark/icon_mini_aabb.svg10
-rw-r--r--editor/icons/dark/icon_mini_array.svg13
-rw-r--r--editor/icons/dark/icon_mini_basis.svg19
-rw-r--r--editor/icons/dark/icon_mini_boolean.svg13
-rw-r--r--editor/icons/dark/icon_mini_color.svg7
-rw-r--r--editor/icons/dark/icon_mini_color_array.svg14
-rw-r--r--editor/icons/dark/icon_mini_dictionary.svg16
-rw-r--r--editor/icons/dark/icon_mini_float.svg15
-rw-r--r--editor/icons/dark/icon_mini_float_array.svg13
-rw-r--r--editor/icons/dark/icon_mini_image.svg17
-rw-r--r--editor/icons/dark/icon_mini_input.svg15
-rw-r--r--editor/icons/dark/icon_mini_int_array.svg8
-rw-r--r--editor/icons/dark/icon_mini_integer.svg14
-rw-r--r--editor/icons/dark/icon_mini_matrix3.svg19
-rw-r--r--editor/icons/dark/icon_mini_object.svg11
-rw-r--r--editor/icons/dark/icon_mini_path.svg14
-rw-r--r--editor/icons/dark/icon_mini_plane.svg12
-rw-r--r--editor/icons/dark/icon_mini_quat.svg12
-rw-r--r--editor/icons/dark/icon_mini_raw_array.svg9
-rw-r--r--editor/icons/dark/icon_mini_rect2.svg19
-rw-r--r--editor/icons/dark/icon_mini_rid.svg14
-rw-r--r--editor/icons/dark/icon_mini_string.svg12
-rw-r--r--editor/icons/dark/icon_mini_string_array.svg10
-rw-r--r--editor/icons/dark/icon_mini_transform.svg7
-rw-r--r--editor/icons/dark/icon_mini_transform2D.svg10
-rw-r--r--editor/icons/dark/icon_mini_variant.svg14
-rw-r--r--editor/icons/dark/icon_mini_vector2.svg15
-rw-r--r--editor/icons/dark/icon_mini_vector2_array.svg12
-rw-r--r--editor/icons/dark/icon_mini_vector3.svg15
-rw-r--r--editor/icons/dark/icon_mini_vector3_array.svg12
-rw-r--r--editor/icons/dark/icon_mirror_x.svg7
-rw-r--r--editor/icons/dark/icon_mirror_y.svg5
-rw-r--r--editor/icons/dark/icon_mouse.svg5
-rw-r--r--editor/icons/dark/icon_move_down.svg6
-rw-r--r--editor/icons/dark/icon_move_point.svg7
-rw-r--r--editor/icons/dark/icon_move_up.svg6
-rw-r--r--editor/icons/dark/icon_multi_edit.svg8
-rw-r--r--editor/icons/dark/icon_multi_line.svg10
-rw-r--r--editor/icons/dark/icon_multi_mesh.svg5
-rw-r--r--editor/icons/dark/icon_multi_mesh_instance.svg6
-rw-r--r--editor/icons/dark/icon_multi_script.svg6
-rw-r--r--editor/icons/dark/icon_native_script.svg5
-rw-r--r--editor/icons/dark/icon_navigation.svg5
-rw-r--r--editor/icons/dark/icon_navigation_2d.svg5
-rw-r--r--editor/icons/dark/icon_navigation_mesh.svg5
-rw-r--r--editor/icons/dark/icon_navigation_mesh_instance.svg8
-rw-r--r--editor/icons/dark/icon_navigation_polygon.svg8
-rw-r--r--editor/icons/dark/icon_navigation_polygon_instance.svg6
-rw-r--r--editor/icons/dark/icon_new.svg8
-rw-r--r--editor/icons/dark/icon_nine_patch_rect.svg12
-rw-r--r--editor/icons/dark/icon_node.svg5
-rw-r--r--editor/icons/dark/icon_node_2d.svg5
-rw-r--r--editor/icons/dark/icon_node_warning.svg7
-rw-r--r--editor/icons/dark/icon_non_favorite.svg5
-rw-r--r--editor/icons/dark/icon_object.svg6
-rw-r--r--editor/icons/dark/icon_occluder_polygon_2d.svg6
-rw-r--r--editor/icons/dark/icon_omni_light.svg5
-rw-r--r--editor/icons/dark/icon_option_button.svg6
-rw-r--r--editor/icons/dark/icon_override.svg6
-rw-r--r--editor/icons/dark/icon_packed_data_container.svg13
-rw-r--r--editor/icons/dark/icon_packed_scene.svg8
-rw-r--r--editor/icons/dark/icon_panel.svg5
-rw-r--r--editor/icons/dark/icon_panel_container.svg5
-rw-r--r--editor/icons/dark/icon_panels_1.svg5
-rw-r--r--editor/icons/dark/icon_panels_2.svg6
-rw-r--r--editor/icons/dark/icon_panels_2_alt.svg6
-rw-r--r--editor/icons/dark/icon_panels_3.svg7
-rw-r--r--editor/icons/dark/icon_panels_3_alt.svg7
-rw-r--r--editor/icons/dark/icon_panels_4.svg8
-rw-r--r--editor/icons/dark/icon_panorama_sky.svg14
-rw-r--r--editor/icons/dark/icon_parallax_background.svg15
-rw-r--r--editor/icons/dark/icon_parallax_layer.svg8
-rw-r--r--editor/icons/dark/icon_particle_attractor_2d.svg9
-rw-r--r--editor/icons/dark/icon_particles.svg11
-rw-r--r--editor/icons/dark/icon_particles_2d.svg5
-rw-r--r--editor/icons/dark/icon_particles_material.svg11
-rw-r--r--editor/icons/dark/icon_path.svg7
-rw-r--r--editor/icons/dark/icon_path_2d.svg7
-rw-r--r--editor/icons/dark/icon_path_follow.svg7
-rw-r--r--editor/icons/dark/icon_path_follow_2d.svg7
-rw-r--r--editor/icons/dark/icon_pause.svg5
-rw-r--r--editor/icons/dark/icon_pin.svg8
-rw-r--r--editor/icons/dark/icon_pin_joint.svg8
-rw-r--r--editor/icons/dark/icon_pin_joint_2d.svg5
-rw-r--r--editor/icons/dark/icon_pin_pressed.svg8
-rw-r--r--editor/icons/dark/icon_plane.svg5
-rw-r--r--editor/icons/dark/icon_plane_mesh.svg5
-rw-r--r--editor/icons/dark/icon_plane_shape.svg5
-rw-r--r--editor/icons/dark/icon_play.svg5
-rw-r--r--editor/icons/dark/icon_play_backwards.svg5
-rw-r--r--editor/icons/dark/icon_play_custom.svg6
-rw-r--r--editor/icons/dark/icon_play_scene.svg8
-rw-r--r--editor/icons/dark/icon_play_start.svg8
-rw-r--r--editor/icons/dark/icon_play_start_backwards.svg8
-rw-r--r--editor/icons/dark/icon_polygon_2_d.svg5
-rw-r--r--editor/icons/dark/icon_polygon_path_finder.svg5
-rw-r--r--editor/icons/dark/icon_popup.svg5
-rw-r--r--editor/icons/dark/icon_popup_dialog.svg5
-rw-r--r--editor/icons/dark/icon_popup_menu.svg6
-rw-r--r--editor/icons/dark/icon_popup_panel.svg6
-rw-r--r--editor/icons/dark/icon_portal.svg5
-rw-r--r--editor/icons/dark/icon_position_2d.svg5
-rw-r--r--editor/icons/dark/icon_position_3d.svg5
-rw-r--r--editor/icons/dark/icon_prism_mesh.svg5
-rw-r--r--editor/icons/dark/icon_procedural_sky.svg14
-rw-r--r--editor/icons/dark/icon_progress_1.svg12
-rw-r--r--editor/icons/dark/icon_progress_2.svg12
-rw-r--r--editor/icons/dark/icon_progress_3.svg12
-rw-r--r--editor/icons/dark/icon_progress_4.svg12
-rw-r--r--editor/icons/dark/icon_progress_5.svg12
-rw-r--r--editor/icons/dark/icon_progress_6.svg12
-rw-r--r--editor/icons/dark/icon_progress_7.svg12
-rw-r--r--editor/icons/dark/icon_progress_8.svg12
-rw-r--r--editor/icons/dark/icon_progress_bar.svg8
-rw-r--r--editor/icons/dark/icon_proximity_group.svg11
-rw-r--r--editor/icons/dark/icon_quad.svg5
-rw-r--r--editor/icons/dark/icon_quad_mesh.svg5
-rw-r--r--editor/icons/dark/icon_quat.svg6
-rw-r--r--editor/icons/dark/icon_range.svg9
-rw-r--r--editor/icons/dark/icon_rating_no_star.svg7
-rw-r--r--editor/icons/dark/icon_rating_star.svg5
-rw-r--r--editor/icons/dark/icon_ray_cast.svg6
-rw-r--r--editor/icons/dark/icon_ray_cast_2d.svg5
-rw-r--r--editor/icons/dark/icon_ray_shape.svg9
-rw-r--r--editor/icons/dark/icon_ray_shape_2d.svg6
-rw-r--r--editor/icons/dark/icon_rayito.svg6
-rw-r--r--editor/icons/dark/icon_real.svg11
-rw-r--r--editor/icons/dark/icon_rectangle_shape_2d.svg5
-rw-r--r--editor/icons/dark/icon_reference_rect.svg12
-rw-r--r--editor/icons/dark/icon_reflection_probe.svg5
-rw-r--r--editor/icons/dark/icon_region_edit.svg13
-rw-r--r--editor/icons/dark/icon_reload.svg6
-rw-r--r--editor/icons/dark/icon_reload_small.svg6
-rw-r--r--editor/icons/dark/icon_remote.svg7
-rw-r--r--editor/icons/dark/icon_remote_transform.svg8
-rw-r--r--editor/icons/dark/icon_remote_transform_2d.svg8
-rw-r--r--editor/icons/dark/icon_remove.svg7
-rw-r--r--editor/icons/dark/icon_rename.svg5
-rw-r--r--editor/icons/dark/icon_reparent.svg6
-rw-r--r--editor/icons/dark/icon_resource_preloader.svg8
-rw-r--r--editor/icons/dark/icon_rich_text_label.svg11
-rw-r--r--editor/icons/dark/icon_rigid_body.svg6
-rw-r--r--editor/icons/dark/icon_rigid_body_2d.svg13
-rw-r--r--editor/icons/dark/icon_room.svg5
-rw-r--r--editor/icons/dark/icon_room_bounds.svg5
-rw-r--r--editor/icons/dark/icon_rotate_0.svg6
-rw-r--r--editor/icons/dark/icon_rotate_180.svg9
-rw-r--r--editor/icons/dark/icon_rotate_270.svg10
-rw-r--r--editor/icons/dark/icon_rotate_90.svg8
-rw-r--r--editor/icons/dark/icon_sample_library.svg6
-rw-r--r--editor/icons/dark/icon_save.svg7
-rw-r--r--editor/icons/dark/icon_script.svg7
-rw-r--r--editor/icons/dark/icon_script_create.svg8
-rw-r--r--editor/icons/dark/icon_script_remove.svg8
-rw-r--r--editor/icons/dark/icon_scroll_bar.svg7
-rw-r--r--editor/icons/dark/icon_scroll_container.svg9
-rw-r--r--editor/icons/dark/icon_search.svg6
-rw-r--r--editor/icons/dark/icon_segment_shape_2d.svg5
-rw-r--r--editor/icons/dark/icon_shader.svg11
-rw-r--r--editor/icons/dark/icon_short_cut.svg6
-rw-r--r--editor/icons/dark/icon_signal.svg9
-rw-r--r--editor/icons/dark/icon_skeleton.svg8
-rw-r--r--editor/icons/dark/icon_slider_joint.svg10
-rw-r--r--editor/icons/dark/icon_slot.svg7
-rw-r--r--editor/icons/dark/icon_snap.svg10
-rw-r--r--editor/icons/dark/icon_sort.svg5
-rw-r--r--editor/icons/dark/icon_sound_room_params.svg9
-rw-r--r--editor/icons/dark/icon_spatial.svg5
-rw-r--r--editor/icons/dark/icon_spatial_material.svg11
-rw-r--r--editor/icons/dark/icon_spatial_sample_player.svg5
-rw-r--r--editor/icons/dark/icon_spatial_stream_player.svg5
-rw-r--r--editor/icons/dark/icon_sphere_mesh.svg5
-rw-r--r--editor/icons/dark/icon_sphere_shape.svg6
-rw-r--r--editor/icons/dark/icon_spin_box.svg8
-rw-r--r--editor/icons/dark/icon_spot_light.svg5
-rw-r--r--editor/icons/dark/icon_sprite.svg5
-rw-r--r--editor/icons/dark/icon_sprite_3d.svg5
-rw-r--r--editor/icons/dark/icon_sprite_frames.svg11
-rw-r--r--editor/icons/dark/icon_static_body.svg5
-rw-r--r--editor/icons/dark/icon_static_body_2d.svg6
-rw-r--r--editor/icons/dark/icon_stop.svg5
-rw-r--r--editor/icons/dark/icon_stream_player.svg5
-rw-r--r--editor/icons/dark/icon_stream_texture.svg5
-rw-r--r--editor/icons/dark/icon_string.svg5
-rw-r--r--editor/icons/dark/icon_style_box_empty.svg10
-rw-r--r--editor/icons/dark/icon_style_box_flat.svg11
-rw-r--r--editor/icons/dark/icon_style_box_texture.svg11
-rw-r--r--editor/icons/dark/icon_tab_container.svg5
-rw-r--r--editor/icons/dark/icon_tabs.svg5
-rw-r--r--editor/icons/dark/icon_test_cube.svg7
-rw-r--r--editor/icons/dark/icon_text_edit.svg6
-rw-r--r--editor/icons/dark/icon_texture_button.svg7
-rw-r--r--editor/icons/dark/icon_texture_progress.svg8
-rw-r--r--editor/icons/dark/icon_texture_rect.svg6
-rw-r--r--editor/icons/dark/icon_theme.svg11
-rw-r--r--editor/icons/dark/icon_thumbnail_wait.svg5
-rw-r--r--editor/icons/dark/icon_tile_map.svg5
-rw-r--r--editor/icons/dark/icon_tile_set.svg5
-rw-r--r--editor/icons/dark/icon_timer.svg8
-rw-r--r--editor/icons/dark/icon_tool_button.svg11
-rw-r--r--editor/icons/dark/icon_tool_move.svg5
-rw-r--r--editor/icons/dark/icon_tool_pan.svg13
-rw-r--r--editor/icons/dark/icon_tool_rotate.svg5
-rw-r--r--editor/icons/dark/icon_tool_scale.svg5
-rw-r--r--editor/icons/dark/icon_tool_select.svg7
-rw-r--r--editor/icons/dark/icon_tools.svg5
-rw-r--r--editor/icons/dark/icon_touch_screen_button.svg5
-rw-r--r--editor/icons/dark/icon_track_add_key.svg5
-rw-r--r--editor/icons/dark/icon_track_add_key_hl.svg6
-rw-r--r--editor/icons/dark/icon_track_continuous.svg5
-rw-r--r--editor/icons/dark/icon_track_discrete.svg7
-rw-r--r--editor/icons/dark/icon_track_trigger.svg9
-rw-r--r--editor/icons/dark/icon_translation.svg5
-rw-r--r--editor/icons/dark/icon_transpose.svg12
-rw-r--r--editor/icons/dark/icon_tree.svg13
-rw-r--r--editor/icons/dark/icon_tween.svg5
-rw-r--r--editor/icons/dark/icon_unbone.svg5
-rw-r--r--editor/icons/dark/icon_ungroup.svg6
-rw-r--r--editor/icons/dark/icon_unlock.svg7
-rw-r--r--editor/icons/dark/icon_uv.svg5
-rw-r--r--editor/icons/dark/icon_v_box_container.svg5
-rw-r--r--editor/icons/dark/icon_v_button_array.svg6
-rw-r--r--editor/icons/dark/icon_v_scroll_bar.svg5
-rw-r--r--editor/icons/dark/icon_v_separator.svg5
-rw-r--r--editor/icons/dark/icon_v_slider.svg10
-rw-r--r--editor/icons/dark/icon_v_split_container.svg8
-rw-r--r--editor/icons/dark/icon_variant.svg16
-rw-r--r--editor/icons/dark/icon_vector.svg6
-rw-r--r--editor/icons/dark/icon_vector2.svg5
-rw-r--r--editor/icons/dark/icon_vehicle_body.svg7
-rw-r--r--editor/icons/dark/icon_vehicle_wheel.svg6
-rw-r--r--editor/icons/dark/icon_video_player.svg7
-rw-r--r--editor/icons/dark/icon_viewport.svg5
-rw-r--r--editor/icons/dark/icon_viewport_container.svg5
-rw-r--r--editor/icons/dark/icon_viewport_sprite.svg10
-rw-r--r--editor/icons/dark/icon_viewport_texture.svg5
-rw-r--r--editor/icons/dark/icon_visibility_enabler.svg9
-rw-r--r--editor/icons/dark/icon_visibility_enabler_2d.svg9
-rw-r--r--editor/icons/dark/icon_visibility_notifier.svg7
-rw-r--r--editor/icons/dark/icon_visibility_notifier_2d.svg5
-rw-r--r--editor/icons/dark/icon_visible.svg6
-rw-r--r--editor/icons/dark/icon_visual_script.svg6
-rw-r--r--editor/icons/dark/icon_visual_shader_port.svg5
-rw-r--r--editor/icons/dark/icon_vu_empty.svg13
-rw-r--r--editor/icons/dark/icon_vu_full.svg12
-rw-r--r--editor/icons/dark/icon_warning.svg5
-rw-r--r--editor/icons/dark/icon_window_dialog.svg5
-rw-r--r--editor/icons/dark/icon_world.svg6
-rw-r--r--editor/icons/dark/icon_world_2d.svg5
-rw-r--r--editor/icons/dark/icon_world_environment.svg8
-rw-r--r--editor/icons/dark/icon_y_sort.svg8
-rw-r--r--editor/icons/dark/icon_zoom.svg5
-rw-r--r--editor/icons/dark/icon_zoom_less.svg5
-rw-r--r--editor/icons/dark/icon_zoom_more.svg12
-rw-r--r--editor/icons/dark/icon_zoom_reset.svg10
-rw-r--r--editor/icons/icon_array_mesh.svg5
-rw-r--r--editor/icons/icon_audio_effect_amplify.svg2
-rw-r--r--editor/icons/icon_clear.svg5
-rw-r--r--editor/icons/icon_collision_polygon_2d.svg (renamed from editor/icons/icon_collision_2d.svg)0
-rw-r--r--editor/icons/icon_cube_mesh.svg2
-rw-r--r--editor/icons/icon_file_big_broken.svg7
-rw-r--r--editor/icons/icon_file_big_dead.svg7
-rw-r--r--editor/icons/icon_file_broken.svg7
-rw-r--r--editor/icons/icon_gizmo_camera.svg5
-rw-r--r--editor/icons/icon_gizmo_directional_light.svg2
-rw-r--r--editor/icons/icon_gizmo_g_i_probe.svg5
-rw-r--r--editor/icons/icon_gizmo_particles.svg5
-rw-r--r--editor/icons/icon_gizmo_reflection_probe.svg5
-rw-r--r--editor/icons/icon_gizmo_spatial_sample_player.svg2
-rw-r--r--editor/icons/icon_gizmo_spot_light.svg5
-rw-r--r--editor/icons/icon_gui_close_dark.svg5
-rw-r--r--editor/icons/icon_gui_close_light.svg5
-rw-r--r--editor/icons/icon_move_down.svg5
-rw-r--r--editor/icons/icon_move_up.svg5
-rw-r--r--editor/icons/icon_multi_mesh.svg2
-rw-r--r--editor/icons/icon_multi_mesh_instance.svg5
-rw-r--r--editor/icons/icon_navigation_mesh_instance.svg3
-rw-r--r--editor/icons/icon_packed_data_container.svg10
-rw-r--r--editor/icons/icon_particle_attractor_2d.svg8
-rw-r--r--editor/icons/icon_particles.svg10
-rw-r--r--editor/icons/icon_reflection_probe.svg6
-rw-r--r--editor/icons/icon_sprite_frames.svg10
-rw-r--r--editor/icons/icon_tile_set.svg2
-rw-r--r--editor/icons/icon_tool_button.svg8
-rw-r--r--editor/icons/icon_transpose.svg11
-rw-r--r--editor/icons/icon_tree.svg9
-rw-r--r--editor/icons/icon_v_slider.svg7
-rw-r--r--editor/icons/icon_v_split_container.svg7
-rw-r--r--editor/icons/icon_vehicle_body.svg6
-rw-r--r--editor/icons/icon_viewport_sprite.svg5
-rw-r--r--editor/icons/icon_visibility_enabler.svg8
-rw-r--r--editor/icons/icon_visibility_enabler_2d.svg8
-rw-r--r--editor/icons/icon_visibility_notifier.svg6
-rw-r--r--editor/icons/icon_visible.svg5
-rw-r--r--editor/icons/icon_world_environment.svg8
-rw-r--r--editor/icons/icon_y_sort.svg7
-rw-r--r--editor/import/editor_import_collada.cpp250
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp4
-rw-r--r--editor/import/resource_importer_scene.cpp7
-rw-r--r--editor/import/resource_importer_scene.h2
-rw-r--r--editor/import/resource_importer_texture.cpp4
-rw-r--r--editor/import/resource_importer_wav.cpp2
-rw-r--r--editor/import_dock.cpp26
-rw-r--r--editor/import_dock.h3
-rw-r--r--editor/node_dock.cpp3
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp113
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h3
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp4
-rw-r--r--editor/plugins/cube_grid_theme_editor_plugin.cpp7
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp2
-rw-r--r--editor/plugins/gradient_editor_plugin.h2
-rw-r--r--editor/plugins/line_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.cpp6
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp19
-rw-r--r--editor/plugins/script_editor_plugin.cpp40
-rw-r--r--editor/plugins/script_text_editor.cpp33
-rw-r--r--editor/plugins/shader_editor_plugin.cpp9
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp169
-rw-r--r--editor/plugins/spatial_editor_plugin.h9
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp14
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp7
-rw-r--r--editor/project_manager.cpp2
-rw-r--r--editor/project_settings_editor.cpp11
-rw-r--r--editor/project_settings_editor.h4
-rw-r--r--editor/property_editor.cpp2
-rw-r--r--editor/quick_open.cpp52
-rw-r--r--editor/quick_open.h1
-rw-r--r--editor/scene_tree_dock.cpp12
-rw-r--r--editor/script_create_dialog.cpp9
-rw-r--r--editor/settings_config_dialog.cpp2
-rw-r--r--editor/spatial_editor_gizmos.cpp51
-rw-r--r--main/main.cpp45
-rw-r--r--main/main.h3
-rw-r--r--main/tests/test_main.cpp6
-rw-r--r--main/tests/test_ordered_hash_map.cpp171
-rw-r--r--main/tests/test_ordered_hash_map.h38
-rw-r--r--main/tests/test_shader_lang.cpp5
-rw-r--r--methods.py53
-rwxr-xr-xmisc/hooks/pre-commit-clang-format4
-rw-r--r--misc/scripts/svgs_2_pngs.py139
-rw-r--r--modules/etc/SCsub6
-rw-r--r--modules/etc/image_etc.cpp2
-rw-r--r--modules/gdnative/SCsub12
-rw-r--r--modules/gdnative/config.py2
-rw-r--r--modules/gdnative/gdnative.cpp42
-rw-r--r--modules/gdnative/gdnative.h24
-rw-r--r--modules/gdnative/gdnative/array.cpp (renamed from modules/gdnative/godot/array.cpp)16
-rw-r--r--modules/gdnative/gdnative/basis.cpp (renamed from modules/gdnative/godot/basis.cpp)20
-rw-r--r--modules/gdnative/gdnative/color.cpp (renamed from modules/gdnative/godot/color.cpp)2
-rw-r--r--modules/gdnative/gdnative/dictionary.cpp (renamed from modules/gdnative/godot/dictionary.cpp)2
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp (renamed from modules/gdnative/godot/gdnative.cpp)3
-rw-r--r--modules/gdnative/gdnative/node_path.cpp (renamed from modules/gdnative/godot/node_path.cpp)2
-rw-r--r--modules/gdnative/gdnative/plane.cpp (renamed from modules/gdnative/godot/plane.cpp)2
-rw-r--r--modules/gdnative/gdnative/pool_arrays.cpp (renamed from modules/gdnative/godot/pool_arrays.cpp)16
-rw-r--r--modules/gdnative/gdnative/quat.cpp (renamed from modules/gdnative/godot/quat.cpp)2
-rw-r--r--modules/gdnative/gdnative/rect2.cpp (renamed from modules/gdnative/godot/rect2.cpp)2
-rw-r--r--modules/gdnative/gdnative/rect3.cpp (renamed from modules/gdnative/godot/rect3.cpp)2
-rw-r--r--modules/gdnative/gdnative/rid.cpp (renamed from modules/gdnative/godot/rid.cpp)2
-rw-r--r--modules/gdnative/gdnative/string.cpp (renamed from modules/gdnative/godot/string.cpp)4
-rw-r--r--modules/gdnative/gdnative/transform.cpp (renamed from modules/gdnative/godot/transform.cpp)2
-rw-r--r--modules/gdnative/gdnative/transform2d.cpp (renamed from modules/gdnative/godot/transform2d.cpp)2
-rw-r--r--modules/gdnative/gdnative/variant.cpp (renamed from modules/gdnative/godot/variant.cpp)2
-rw-r--r--modules/gdnative/gdnative/vector2.cpp (renamed from modules/gdnative/godot/vector2.cpp)2
-rw-r--r--modules/gdnative/gdnative/vector3.cpp (renamed from modules/gdnative/godot/vector3.cpp)2
-rw-r--r--modules/gdnative/godot/icon.png.import23
-rw-r--r--modules/gdnative/include/gdnative/array.h (renamed from modules/gdnative/godot/array.h)8
-rw-r--r--modules/gdnative/include/gdnative/basis.h (renamed from modules/gdnative/godot/basis.h)12
-rw-r--r--modules/gdnative/include/gdnative/color.h (renamed from modules/gdnative/godot/color.h)4
-rw-r--r--modules/gdnative/include/gdnative/dictionary.h (renamed from modules/gdnative/godot/dictionary.h)8
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h (renamed from modules/gdnative/godot/gdnative.h)62
-rw-r--r--modules/gdnative/include/gdnative/node_path.h (renamed from modules/gdnative/godot/node_path.h)6
-rw-r--r--modules/gdnative/include/gdnative/plane.h (renamed from modules/gdnative/godot/plane.h)4
-rw-r--r--modules/gdnative/include/gdnative/pool_arrays.h (renamed from modules/gdnative/godot/pool_arrays.h)24
-rw-r--r--modules/gdnative/include/gdnative/quat.h (renamed from modules/gdnative/godot/quat.h)4
-rw-r--r--modules/gdnative/include/gdnative/rect2.h (renamed from modules/gdnative/godot/rect2.h)4
-rw-r--r--modules/gdnative/include/gdnative/rect3.h (renamed from modules/gdnative/godot/rect3.h)6
-rw-r--r--modules/gdnative/include/gdnative/rid.h (renamed from modules/gdnative/godot/rid.h)4
-rw-r--r--modules/gdnative/include/gdnative/string.h (renamed from modules/gdnative/godot/string.h)8
-rw-r--r--modules/gdnative/include/gdnative/transform.h (renamed from modules/gdnative/godot/transform.h)8
-rw-r--r--modules/gdnative/include/gdnative/transform2d.h (renamed from modules/gdnative/godot/transform2d.h)6
-rw-r--r--modules/gdnative/include/gdnative/variant.h (renamed from modules/gdnative/godot/variant.h)40
-rw-r--r--modules/gdnative/include/gdnative/vector2.h (renamed from modules/gdnative/godot/vector2.h)2
-rw-r--r--modules/gdnative/include/gdnative/vector3.h (renamed from modules/gdnative/godot/vector3.h)4
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h (renamed from modules/nativescript/godot_nativescript.h)6
-rw-r--r--modules/gdnative/nativescript/SCsub (renamed from modules/nativescript/SCsub)0
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp (renamed from modules/nativescript/api_generator.cpp)82
-rw-r--r--modules/gdnative/nativescript/api_generator.h (renamed from modules/nativescript/api_generator.h)0
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp (renamed from modules/nativescript/godot_nativescript.cpp)8
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp (renamed from modules/nativescript/nativescript.cpp)4
-rw-r--r--modules/gdnative/nativescript/nativescript.h (renamed from modules/nativescript/nativescript.h)2
-rw-r--r--modules/gdnative/nativescript/register_types.cpp (renamed from modules/nativescript/register_types.cpp)0
-rw-r--r--modules/gdnative/nativescript/register_types.h (renamed from modules/nativescript/register_types.h)0
-rw-r--r--modules/gdnative/register_types.cpp176
-rw-r--r--modules/gdscript/gd_editor.cpp10
-rw-r--r--modules/gdscript/gd_function.cpp8
-rw-r--r--modules/gdscript/gd_functions.cpp32
-rw-r--r--modules/gdscript/gd_parser.cpp8
-rw-r--r--modules/gdscript/gd_script.h1
-rw-r--r--modules/gridmap/grid_map.cpp6
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp4
-rw-r--r--modules/hdr/image_loader_hdr.cpp2
-rw-r--r--modules/hdr/image_loader_hdr.h2
-rw-r--r--modules/nativescript/config.py8
-rw-r--r--modules/openssl/SCsub2
-rw-r--r--modules/regex/SCsub50
-rw-r--r--modules/regex/regex.cpp1560
-rw-r--r--modules/regex/regex.h47
-rw-r--r--modules/squish/image_compress_squish.cpp6
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp5
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.h3
-rw-r--r--modules/svg/image_loader_svg.cpp51
-rw-r--r--modules/svg/image_loader_svg.h7
-rw-r--r--modules/tga/image_loader_tga.cpp12
-rw-r--r--modules/tga/image_loader_tga.h2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h2
-rw-r--r--modules/visual_script/visual_script.h1
-rw-r--r--modules/visual_script/visual_script_editor.cpp28
-rw-r--r--modules/visual_script/visual_script_expression.cpp2
-rw-r--r--modules/visual_script/visual_script_nodes.cpp9
-rw-r--r--modules/visual_script/visual_script_nodes.h2
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp2
-rw-r--r--modules/webm/video_stream_webm.cpp2
-rw-r--r--modules/webm/video_stream_webm.h2
-rw-r--r--platform/android/audio_driver_opensl.cpp2
-rw-r--r--platform/android/detect.py2
-rw-r--r--platform/android/export/export.cpp139
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java255
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotLib.java5
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java2
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java94
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java43
-rw-r--r--platform/android/java_glue.cpp238
-rw-r--r--platform/android/java_glue.h3
-rw-r--r--platform/iphone/icloud.h2
-rw-r--r--platform/iphone/icloud.mm2
-rw-r--r--platform/javascript/os_javascript.cpp31
-rw-r--r--platform/osx/audio_driver_osx.cpp26
-rw-r--r--platform/osx/audio_driver_osx.h5
-rw-r--r--platform/osx/joypad_osx.h2
-rw-r--r--platform/osx/os_osx.h2
-rw-r--r--platform/osx/os_osx.mm40
-rw-r--r--platform/osx/power_osx.cpp2
-rw-r--r--platform/uwp/export/export.cpp12
-rw-r--r--platform/windows/joypad.cpp2
-rw-r--r--platform/windows/joypad.h2
-rw-r--r--platform/x11/detect.py9
-rw-r--r--platform/x11/os_x11.cpp2
-rw-r--r--scene/2d/audio_stream_player_2d.cpp4
-rw-r--r--scene/2d/canvas_item.h4
-rw-r--r--scene/2d/light_2d.cpp2
-rw-r--r--scene/2d/light_2d.h1
-rw-r--r--scene/2d/line_builder.cpp2
-rw-r--r--scene/2d/navigation2d.cpp26
-rw-r--r--scene/2d/physics_body_2d.cpp2
-rw-r--r--scene/2d/tile_map.cpp30
-rw-r--r--scene/2d/tile_map.h7
-rw-r--r--scene/3d/arvr_nodes.cpp2
-rw-r--r--scene/3d/audio_stream_player_3d.cpp10
-rw-r--r--scene/3d/collision_shape.cpp2
-rw-r--r--scene/3d/collision_shape.h2
-rw-r--r--scene/3d/gi_probe.cpp4
-rw-r--r--scene/3d/immediate_geometry.h2
-rw-r--r--scene/3d/light.cpp6
-rw-r--r--scene/3d/light.h1
-rw-r--r--scene/3d/physics_body.cpp229
-rw-r--r--scene/3d/physics_body.h52
-rw-r--r--scene/3d/remote_transform.cpp3
-rw-r--r--scene/animation/animation_tree_player.h2
-rw-r--r--scene/animation/tween.cpp24
-rw-r--r--scene/audio/audio_player.cpp4
-rw-r--r--scene/gui/check_box.h2
-rw-r--r--scene/gui/control.cpp2
-rw-r--r--scene/gui/graph_node.cpp20
-rw-r--r--scene/gui/graph_node.h6
-rw-r--r--scene/gui/item_list.cpp20
-rw-r--r--scene/gui/item_list.h4
-rw-r--r--scene/gui/label.cpp26
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/patch_9_rect.cpp10
-rw-r--r--scene/gui/patch_9_rect.h4
-rw-r--r--scene/gui/rich_text_label.cpp27
-rw-r--r--scene/gui/rich_text_label.h2
-rw-r--r--scene/gui/text_edit.cpp31
-rw-r--r--scene/gui/tree.cpp6
-rw-r--r--scene/gui/tree.h2
-rw-r--r--scene/main/scene_tree.cpp6
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/main/viewport.cpp30
-rw-r--r--scene/main/viewport.h15
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/animation.cpp11
-rw-r--r--scene/resources/color_ramp.h7
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/environment.cpp8
-rw-r--r--scene/resources/font.cpp5
-rw-r--r--scene/resources/material.cpp143
-rw-r--r--scene/resources/material.h30
-rw-r--r--scene/resources/mesh_library.cpp5
-rw-r--r--scene/resources/mesh_library.h2
-rw-r--r--scene/resources/packed_scene.cpp2
-rw-r--r--scene/resources/scene_format_text.cpp5
-rw-r--r--scene/resources/scene_format_text.h2
-rw-r--r--scene/resources/style_box.cpp30
-rw-r--r--scene/resources/style_box.h12
-rw-r--r--scene/resources/surface_tool.cpp15
-rw-r--r--scene/resources/surface_tool.h2
-rw-r--r--scene/resources/texture.cpp4
-rw-r--r--servers/audio/audio_driver_dummy.cpp17
-rw-r--r--servers/audio/audio_driver_dummy.h3
-rw-r--r--servers/audio/audio_rb_resampler.cpp8
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp2
-rw-r--r--servers/audio_server.cpp23
-rw-r--r--servers/audio_server.h3
-rw-r--r--servers/physics/collision_object_sw.cpp32
-rw-r--r--servers/physics/collision_object_sw.h2
-rw-r--r--servers/physics/collision_solver_sw.cpp2
-rw-r--r--servers/physics/gjk_epa.cpp6
-rw-r--r--servers/physics/physics_server_sw.cpp21
-rw-r--r--servers/physics/physics_server_sw.h4
-rw-r--r--servers/physics/shape_sw.cpp10
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp4
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp3
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h1
-rw-r--r--servers/physics_2d/space_2d_sw.cpp60
-rw-r--r--servers/physics_server.cpp2
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/shader_language.cpp53
-rw-r--r--servers/visual/shader_language.h17
-rw-r--r--servers/visual/shader_types.cpp261
-rw-r--r--servers/visual/shader_types.h4
-rw-r--r--servers/visual/visual_server_raster.h1
-rw-r--r--servers/visual/visual_server_scene.cpp49
-rw-r--r--servers/visual/visual_server_wrap_mt.h1
-rw-r--r--servers/visual_server.cpp1
-rw-r--r--servers/visual_server.h9
-rw-r--r--thirdparty/README.md30
-rw-r--r--thirdparty/fonts/DroidSans.ttfbin190044 -> 0 bytes
-rw-r--r--thirdparty/fonts/DroidSansArabic.ttfbin35908 -> 0 bytes
-rw-r--r--thirdparty/fonts/DroidSansHebrew.ttfbin23076 -> 0 bytes
-rw-r--r--thirdparty/fonts/LICENSE.Noto.txt92
-rw-r--r--thirdparty/fonts/NotoNaskhArabicUI_Regular.ttfbin0 -> 256116 bytes
-rw-r--r--thirdparty/fonts/NotoSansHebrew_Regular.ttfbin0 -> 27124 bytes
-rw-r--r--thirdparty/fonts/NotoSansThaiUI_Regular.ttf (renamed from thirdparty/fonts/DroidSansThai.ttf)bin36028 -> 34852 bytes
-rw-r--r--thirdparty/fonts/NotoSansUI_Regular.ttfbin0 -> 305888 bytes
-rw-r--r--thirdparty/fonts/source_code_pro.otfbin140088 -> 145556 bytes
-rw-r--r--thirdparty/pcre2/AUTHORS36
-rw-r--r--thirdparty/pcre2/LICENCE83
-rw-r--r--thirdparty/pcre2/src/config.h359
-rw-r--r--thirdparty/pcre2/src/pcre2.h771
-rw-r--r--thirdparty/pcre2/src/pcre2_auto_possess.c1293
-rw-r--r--thirdparty/pcre2/src/pcre2_chartables.c198
-rw-r--r--thirdparty/pcre2/src/pcre2_compile.c9517
-rw-r--r--thirdparty/pcre2/src/pcre2_config.c218
-rw-r--r--thirdparty/pcre2/src/pcre2_context.c391
-rw-r--r--thirdparty/pcre2/src/pcre2_dfa_match.c3628
-rw-r--r--thirdparty/pcre2/src/pcre2_error.c325
-rw-r--r--thirdparty/pcre2/src/pcre2_find_bracket.c218
-rw-r--r--thirdparty/pcre2/src/pcre2_internal.h1940
-rw-r--r--thirdparty/pcre2/src/pcre2_intmodedep.h862
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_compile.c11501
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_match.c189
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_misc.c227
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_test.c1735
-rw-r--r--thirdparty/pcre2/src/pcre2_maketables.c157
-rw-r--r--thirdparty/pcre2/src/pcre2_match.c7238
-rw-r--r--thirdparty/pcre2/src/pcre2_match_data.c147
-rw-r--r--thirdparty/pcre2/src/pcre2_newline.c243
-rw-r--r--thirdparty/pcre2/src/pcre2_ord2utf.c120
-rw-r--r--thirdparty/pcre2/src/pcre2_pattern_info.c410
-rw-r--r--thirdparty/pcre2/src/pcre2_printint.c832
-rw-r--r--thirdparty/pcre2/src/pcre2_serialize.c265
-rw-r--r--thirdparty/pcre2/src/pcre2_string_utils.c201
-rw-r--r--thirdparty/pcre2/src/pcre2_study.c1625
-rw-r--r--thirdparty/pcre2/src/pcre2_substitute.c858
-rw-r--r--thirdparty/pcre2/src/pcre2_substring.c542
-rw-r--r--thirdparty/pcre2/src/pcre2_tables.c765
-rw-r--r--thirdparty/pcre2/src/pcre2_ucd.c3747
-rw-r--r--thirdparty/pcre2/src/pcre2_ucp.h268
-rw-r--r--thirdparty/pcre2/src/pcre2_valid_utf.c398
-rw-r--r--thirdparty/pcre2/src/pcre2_xclass.c271
-rw-r--r--thirdparty/pcre2/src/sljit/sljitConfig.h145
-rw-r--r--thirdparty/pcre2/src/sljit/sljitConfigInternal.h724
-rw-r--r--thirdparty/pcre2/src/sljit/sljitExecAllocator.c312
-rw-r--r--thirdparty/pcre2/src/sljit/sljitLir.c2067
-rw-r--r--thirdparty/pcre2/src/sljit/sljitLir.h1269
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_32.c2583
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_64.c2062
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c2102
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c368
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c471
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c2147
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_32.c271
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_64.c423
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_common.c2393
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c166
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c1450
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c10159
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c2563
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_32.c550
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_64.c725
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_common.c3030
-rw-r--r--thirdparty/pcre2/src/sljit/sljitUtils.c337
1030 files changed, 101426 insertions, 10430 deletions
diff --git a/AUTHORS.md b/AUTHORS.md
index 84b0754929..bf833d1435 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -47,11 +47,13 @@ name is available.
Geequlim
Gen (dbsGen)
George Marques (vnen)
+ Gilles Roudiere (groud)
Guilherme Felipe (guilhermefelipecgs)
Hein-Pieter van Braam (hpvb)
Hubert Jarosz (Marqin)
Hugo Locurcio (Calinou)
Ignacio Etcheverry (neikeq)
+ Indah Sylvia (ISylvox)
J08nY
Jakub Grzesik (kubecz3k)
Johan Manuel (29jm)
@@ -77,18 +79,21 @@ name is available.
Ramesh Ravone (RameshRavone)
Ray Koopa (RayKoopa)
Rémi Verschelde (akien-mga)
+ Ruslan Mustakov (endragor)
+ Saniko (sanikoyes)
SaracenOne
Theo Hallenius (TheoXD)
Thomas Herzog (karroffel)
Timo (toger5)
V. Vamsi Krishna (vkbsb)
Vinzenz Feenstra (vinzenz)
+ Wilson E. Alvarez (Rubonnek)
Zher Huei Lee (leezh)
ZuBsPaCe
박한얼 (volzhs)
+ bruvzg
est31
marynate
mrezai
romulox-x
- sanikoyes
yg2f (SuperUserNameMan)
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 92e68060c6..13edd896ef 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -145,6 +145,11 @@ Comment: DroidSans font
Copyright: 2008, The Android Open Source Project
License: Apache-2.0
+Files: ./thirdparty/fonts/NotoSans*.ttf
+Comment: Noto Sans font
+Copyright: 2012, Google Inc.
+License: OFL-1.1
+
Files: ./thirdparty/fonts/source_code_pro.otf
Comment: Source Code Pro font
Copyright: 2010, 2012, Adobe Systems Incorporated
diff --git a/DONORS.md b/DONORS.md
new file mode 100644
index 0000000000..09049ede48
--- /dev/null
+++ b/DONORS.md
@@ -0,0 +1,141 @@
+# Donors to the Godot Engine project
+
+Godot Engine is a non-profit project developed by a community of voluntary
+contributors, as well as occasional paid contributors thanks to the financial
+support of generous donors.
+
+The ways to donate to the project, as well as details on how the funds are
+used, are described on [Godot's website](https://godotengine.org/donate).
+
+The following is a list of the current monthly donors, to be have their
+generous deed immortalized in the next stable release of Godot Engine.
+
+## Platinum sponsors
+
+None so far, but your company could be the first! :)
+
+## Gold sponsors
+
+ Gamblify <https://www.gamblify.com>
+
+## Mini sponsors
+
+ Arron Washington
+ Chrisartguy
+ Christian Uldall Pedersen
+ Hein-Pieter van Braam
+ Matthieu Huvé
+ Neal Gompa (Conan Kudo)
+ Olimpiu Metiu
+ Ruslan Mustakov
+
+## Gold donors
+
+ Alexander Otto
+ Jake Bo
+ Javier
+ Nathan Warden
+ Ranoller
+ Rémi Verschelde
+ Stephan Lanfermann
+
+ Andreas Schüle
+ Bernhard Liebl
+ Jordan M Lucas
+
+ BanjoNode2D
+ Chris Serino
+ Conrad Curry
+ Craig Smith
+ David Churchill
+ Dean Harmon
+ Guilherme Felipe de C. G. da Silva
+ Henrique Alves
+ Laurence Bannister
+ Leo
+ Przemysław Gołąb (n-pigeon)
+ Robert Willes
+ Robin Arys
+ summerblind
+ Testus Maximus
+ Thomas Bjarnelöf
+
+ Amanda Haldy
+ Andreas Haas
+ Bryanna M
+ Cody Parker
+ D
+ Ezra Theunissen
+ flesk
+ François Cantin
+ Hendrik Mans
+ Jeppe Zapp
+ Johannes Wuensch
+ Justin Arnold
+ Justo Delgado Baudí
+ Leandro Voltolino
+ Myles
+ Robert Podgorski
+ Scott Beacon
+ x1212
+
+## Silver donors
+
+ Alex Barsukov
+ Avencherus
+ Bastian Böhm
+ Ben Vercammen
+ Bryan Stevenson
+ Collin Shooltz
+ Fabian Becker
+ fengjiongmax
+ Geequlim
+ Gerrit Großkopf
+ Guldoman
+ hatniX
+ HeartBeast
+ Heribert Hirth
+ Hunter Jones
+ imekon
+ Jacob McKenney
+ Jonathon
+ Josh 'Cheeseness' Bush
+ Julian Murgia
+ Juraj Móza
+ Kevin Boyer
+ Klavdij Voncina
+ Lisandro Lorea
+ magodev
+ Martin Novák
+ Matthew Fitzpatrick
+ Matthew Valancy
+ Matthias Hölzl
+ Max R.R. Collada
+ Michael Gringauz
+ Mikael Olsson
+ Moritz Laass
+ nee
+ nvgrod
+ Pablo Seibelt
+ Pan Ip
+ Paul Mason
+ Paweł Kowal
+ Pietro Vertechi
+ rayos
+ Richman Stewart
+ Roger Smith
+ Sam Van Campenhout
+ Sam Vila
+ Sasori Olkof
+ Sootstone
+ Tavo Tell
+ Tom Larrow
+ Trent McPheron
+ Troy Bonneau
+ UltyX
+ Xananax & karroffel
+
+## Bronze donors
+
+There are even more donors that support the project with a small monthly donation.
+Every bit counts and we thank every one of them for their amazing support!
diff --git a/SConstruct b/SConstruct
index fee9786234..9a3ee03ed5 100644
--- a/SConstruct
+++ b/SConstruct
@@ -167,6 +167,7 @@ opts.Add('builtin_libvpx', "Use the builtin libvpx library (yes/no)", 'yes')
opts.Add('builtin_libwebp', "Use the builtin libwebp library (yes/no)", 'yes')
opts.Add('builtin_openssl', "Use the builtin openssl library (yes/no)", 'yes')
opts.Add('builtin_opus', "Use the builtin opus library (yes/no)", 'yes')
+opts.Add('builtin_pcre2', "Use the builtin pcre2 library (yes/no)", 'yes')
opts.Add('builtin_squish', "Use the builtin squish library (yes/no)", 'yes')
opts.Add('builtin_zlib', "Use the builtin zlib library (yes/no)", 'yes')
@@ -409,44 +410,7 @@ if selected_platform in platform_list:
# Microsoft Visual Studio Project Generation
if (env['vsproj']) == "yes":
-
- AddToVSProject(env.core_sources)
- AddToVSProject(env.main_sources)
- AddToVSProject(env.modules_sources)
- AddToVSProject(env.scene_sources)
- AddToVSProject(env.servers_sources)
- AddToVSProject(env.editor_sources)
-
- # this env flag won't work, it needs to be set in env_base=Environment(MSVC_VERSION='9.0')
- # Even then, SCons still seems to ignore it and builds with the latest MSVC...
- # That said, it's not needed to be set so far but I'm leaving it here so that this comment
- # has a purpose.
- # env['MSVS_VERSION']='9.0'
-
- # Calls a CMD with /C(lose) and /V(delayed environment variable expansion) options.
- # And runs vcvarsall bat for the proper architecture and scons for proper configuration
- env['MSVSBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! -j2'
- env['MSVSREBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) & call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j2'
- env['MSVSCLEANCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons --clean platform=windows target=$(Configuration) tools=!tools! -j2'
-
- # This version information (Win32, x64, Debug, Release, Release_Debug seems to be
- # required for Visual Studio to understand that it needs to generate an NMAKE
- # project. Do not modify without knowing what you are doing.
- debug_variants = ['debug|Win32'] + ['debug|x64']
- release_variants = ['release|Win32'] + ['release|x64']
- release_debug_variants = ['release_debug|Win32'] + ['release_debug|x64']
- variants = debug_variants + release_variants + release_debug_variants
- debug_targets = ['bin\\godot.windows.tools.32.exe'] + ['bin\\godot.windows.tools.64.exe']
- release_targets = ['bin\\godot.windows.opt.32.exe'] + ['bin\\godot.windows.opt.64.exe']
- release_debug_targets = ['bin\\godot.windows.opt.tools.32.exe'] + ['bin\\godot.windows.opt.tools.64.exe']
- targets = debug_targets + release_targets + release_debug_targets
- msvproj = env.MSVSProject(target=['#godot' + env['MSVSPROJECTSUFFIX']],
- incs=env.vs_incs,
- srcs=env.vs_srcs,
- runfile=targets,
- buildtarget=targets,
- auto_build_solution=1,
- variant=variants)
+ methods.generate_vs_project(env, GetOption("num_jobs"))
else:
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index abe8b9b715..0f217c8235 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -568,7 +568,7 @@ Dictionary _OS::get_time(bool utc) const {
}
/**
- * Get a epoch time value from a dictionary of time values
+ * Get an epoch time value from a dictionary of time values
* @p datetime must be populated with the following keys:
* day, hour, minute, month, second, year. (dst is ignored).
*
@@ -1705,7 +1705,7 @@ Variant _File::get_var() const {
ERR_FAIL_COND_V(!f, Variant());
uint32_t len = get_32();
PoolVector<uint8_t> buff = get_buffer(len);
- ERR_FAIL_COND_V(buff.size() != len, Variant());
+ ERR_FAIL_COND_V((uint32_t)buff.size() != len, Variant());
PoolVector<uint8_t>::Read r = buff.read();
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 4b0e1b31f0..f5ddd9c761 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -46,11 +46,6 @@
#ifdef DEBUG_METHODS_ENABLED
-ParamDef::ParamDef(const Variant &p_variant)
- : used(true),
- val(p_variant) {
-}
-
MethodDefinition D_METHOD(const char *p_name) {
MethodDefinition md;
@@ -539,8 +534,13 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
}
minfo.return_val = method->get_return_info();
-
minfo.flags = method->get_hint_flags();
+
+ for (int i = 0; i < method->get_argument_count(); i++) {
+ if (method->has_default_argument(i))
+ minfo.default_arguments.push_back(method->get_default_argument(i));
+ }
+
p_methods->push_back(minfo);
}
diff --git a/core/class_db.h b/core/class_db.h
index 25a5000572..f6b97748b0 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -38,29 +38,6 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
-struct ParamHint {
-
- String name;
- PropertyHint hint;
- String hint_text;
- Variant default_val;
-
- ParamHint(const String &p_name = "", PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_text = "", const Variant &p_default_val = Variant())
- : name(p_name),
- hint(p_hint),
- hint_text(p_hint_text),
- default_val(p_default_val) {
- }
-};
-
-struct ParamDef {
- bool used;
- Variant val;
- _FORCE_INLINE_ ParamDef() { used = false; }
- ParamDef(const Variant &p_variant);
-};
-
-//#define DEFVAL( m_defval ) ParamDef(m_defval)
#define DEFVAL(m_defval) (m_defval)
//#define SIMPLE_METHODDEF
diff --git a/core/color.cpp b/core/color.cpp
index 356e8c168c..ab264d31d4 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -47,6 +47,18 @@ uint32_t Color::to_ARGB32() const {
return c;
}
+uint32_t Color::to_ABGR32() const {
+ uint32_t c = (uint8_t)(a * 255);
+ c <<= 8;
+ c |= (uint8_t)(b * 255);
+ c <<= 8;
+ c |= (uint8_t)(g * 255);
+ c <<= 8;
+ c |= (uint8_t)(r * 255);
+
+ return c;
+}
+
uint32_t Color::to_32() const {
uint32_t c = (uint8_t)(a * 255);
diff --git a/core/color.h b/core/color.h
index 6df114f2f2..cd5510cf01 100644
--- a/core/color.h
+++ b/core/color.h
@@ -53,6 +53,7 @@ struct Color {
uint32_t to_32() const;
uint32_t to_ARGB32() const;
+ uint32_t to_ABGR32() const;
float gray() const;
float get_h() const;
float get_s() const;
@@ -148,8 +149,7 @@ struct Color {
b < 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a);
}
- static Color
- hex(uint32_t p_hex);
+ static Color hex(uint32_t p_hex);
static Color html(const String &p_color);
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
diff --git a/core/hash_map.h b/core/hash_map.h
index b22c6378b0..37391a4c83 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -102,17 +102,31 @@ public:
}
};
-private:
- struct Entry {
+ struct Element {
+ private:
+ friend class HashMap;
uint32_t hash;
- Entry *next;
+ Element *next;
+ Element() { next = 0; }
Pair pair;
- Entry() { next = 0; }
+ public:
+ const TKey &key() const {
+ return pair.key;
+ }
+
+ TData &value() {
+ return pair.data;
+ }
+
+ const TData &value() const {
+ return pair.value();
+ }
};
- Entry **hash_table;
+private:
+ Element **hash_table;
uint8_t hash_table_power;
uint32_t elements;
@@ -120,7 +134,7 @@ private:
ERR_FAIL_COND(hash_table);
- hash_table = memnew_arr(Entry *, (1 << MIN_HASH_TABLE_POWER));
+ hash_table = memnew_arr(Element *, (1 << MIN_HASH_TABLE_POWER));
hash_table_power = MIN_HASH_TABLE_POWER;
elements = 0;
@@ -168,7 +182,7 @@ private:
if (new_hash_table_power == -1)
return;
- Entry **new_hash_table = memnew_arr(Entry *, (1 << new_hash_table_power));
+ Element **new_hash_table = memnew_arr(Element *, (1 << new_hash_table_power));
if (!new_hash_table) {
ERR_PRINT("Out of Memory");
@@ -184,7 +198,7 @@ private:
while (hash_table[i]) {
- Entry *se = hash_table[i];
+ Element *se = hash_table[i];
hash_table[i] = se->next;
int new_pos = se->hash & ((1 << new_hash_table_power) - 1);
se->next = new_hash_table[new_pos];
@@ -199,12 +213,12 @@ private:
}
/* I want to have only one function.. */
- _FORCE_INLINE_ const Entry *get_entry(const TKey &p_key) const {
+ _FORCE_INLINE_ const Element *get_element(const TKey &p_key) const {
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
- Entry *e = hash_table[index];
+ Element *e = hash_table[index];
while (e) {
@@ -221,10 +235,10 @@ private:
return NULL;
}
- Entry *create_entry(const TKey &p_key) {
+ Element *create_element(const TKey &p_key) {
- /* if entry doesn't exist, create it */
- Entry *e = memnew(Entry);
+ /* if element doesn't exist, create it */
+ Element *e = memnew(Element);
ERR_FAIL_COND_V(!e, NULL); /* out of memory */
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
@@ -248,7 +262,7 @@ private:
if (!p_t.hash_table || p_t.hash_table_power == 0)
return; /* not copying from empty table */
- hash_table = memnew_arr(Entry *, 1 << p_t.hash_table_power);
+ hash_table = memnew_arr(Element *, 1 << p_t.hash_table_power);
hash_table_power = p_t.hash_table_power;
elements = p_t.elements;
@@ -256,11 +270,11 @@ private:
hash_table[i] = NULL;
- const Entry *e = p_t.hash_table[i];
+ const Element *e = p_t.hash_table[i];
while (e) {
- Entry *le = memnew(Entry); /* local entry */
+ Element *le = memnew(Element); /* local element */
*le = *e; /* copy data */
@@ -274,30 +288,30 @@ private:
}
public:
- void set(const TKey &p_key, const TData &p_data) {
-
- set(Pair(p_key, p_data));
+ Element *set(const TKey &p_key, const TData &p_data) {
+ return set(Pair(p_key, p_data));
}
- void set(const Pair &p_pair) {
+ Element *set(const Pair &p_pair) {
- Entry *e = NULL;
+ Element *e = NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
- e = const_cast<Entry *>(get_entry(p_pair.key));
+ e = const_cast<Element *>(get_element(p_pair.key));
/* if we made it up to here, the pair doesn't exist, create and assign */
if (!e) {
- e = create_entry(p_pair.key);
+ e = create_element(p_pair.key);
if (!e)
- return;
+ return NULL;
check_hash_table(); // perform mantenience routine
}
e->pair.data = p_pair.data;
+ return e;
}
bool has(const TKey &p_key) const {
@@ -335,7 +349,7 @@ public:
if (!hash_table)
return NULL;
- Entry *e = const_cast<Entry *>(get_entry(p_key));
+ Element *e = const_cast<Element *>(get_element(p_key));
if (e)
return &e->pair.data;
@@ -348,7 +362,7 @@ public:
if (!hash_table)
return NULL;
- const Entry *e = const_cast<Entry *>(get_entry(p_key));
+ const Element *e = const_cast<Element *>(get_element(p_key));
if (e)
return &e->pair.data;
@@ -370,7 +384,7 @@ public:
uint32_t hash = p_custom_hash;
uint32_t index = hash & ((1 << hash_table_power) - 1);
- Entry *e = hash_table[index];
+ Element *e = hash_table[index];
while (e) {
@@ -396,7 +410,7 @@ public:
uint32_t hash = p_custom_hash;
uint32_t index = hash & ((1 << hash_table_power) - 1);
- const Entry *e = hash_table[index];
+ const Element *e = hash_table[index];
while (e) {
@@ -425,8 +439,8 @@ public:
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
- Entry *e = hash_table[index];
- Entry *p = NULL;
+ Element *e = hash_table[index];
+ Element *p = NULL;
while (e) {
/* checking hash first avoids comparing key, which may take longer */
@@ -463,16 +477,16 @@ public:
}
inline TData &operator[](const TKey &p_key) { //assignment
- Entry *e = NULL;
+ Element *e = NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
- e = const_cast<Entry *>(get_entry(p_key));
+ e = const_cast<Element *>(get_element(p_key));
/* if we made it up to here, the pair doesn't exist, create */
if (!e) {
- e = create_entry(p_key);
+ e = create_element(p_key);
CRASH_COND(!e);
check_hash_table(); // perform mantenience routine
}
@@ -510,14 +524,14 @@ public:
} else { /* get the next key */
- const Entry *e = get_entry(*p_key);
+ const Element *e = get_element(*p_key);
ERR_FAIL_COND_V(!e, NULL); /* invalid key supplied */
if (e->next) {
/* if there is a "next" in the list, return that */
return &e->next->pair.key;
} else {
- /* go to next entries */
+ /* go to next elements */
uint32_t index = e->hash & ((1 << hash_table_power) - 1);
index++;
for (int i = index; i < (1 << hash_table_power); i++) {
@@ -552,7 +566,7 @@ public:
while (hash_table[i]) {
- Entry *e = hash_table[i];
+ Element *e = hash_table[i];
hash_table[i] = e->next;
memdelete(e);
}
@@ -582,7 +596,7 @@ public:
return;
for (int i = 0; i < (1 << hash_table_power); i++) {
- Entry *e = hash_table[i];
+ Element *e = hash_table[i];
while (e) {
*p_pairs = &e->pair;
p_pairs++;
@@ -596,7 +610,7 @@ public:
return;
for (int i = 0; i < (1 << hash_table_power); i++) {
- Entry *e = hash_table[i];
+ Element *e = hash_table[i];
while (e) {
p_keys->push_back(e->pair.key);
e = e->next;
diff --git a/core/helper/math_fieldwise.cpp b/core/helper/math_fieldwise.cpp
index 2ce2a70866..228611f8b3 100644
--- a/core/helper/math_fieldwise.cpp
+++ b/core/helper/math_fieldwise.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* fieldwise.cpp */
+/* math_fieldwise.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/core/helper/math_fieldwise.h b/core/helper/math_fieldwise.h
index 4671703f41..400df040a4 100644
--- a/core/helper/math_fieldwise.h
+++ b/core/helper/math_fieldwise.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* fieldwise.h */
+/* math_fieldwise.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/core/image.cpp b/core/image.cpp
index bb1ce2cee3..4d1f32c360 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1256,9 +1256,9 @@ void Image::create(const char **p_xpm) {
if (*line_ptr == '#') {
line_ptr++;
- uint8_t col_r;
- uint8_t col_g;
- uint8_t col_b;
+ uint8_t col_r = 0;
+ uint8_t col_g = 0;
+ uint8_t col_b = 0;
//uint8_t col_a=255;
for (int i = 0; i < 6; i++) {
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index 2fe1428752..ba84c9767c 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -37,11 +37,11 @@ class FileAccessCompressed : public FileAccess {
Compression::Mode cmode;
bool writing;
- int write_pos;
+ uint32_t write_pos;
uint8_t *write_ptr;
- int write_buffer_size;
- int write_max;
- int block_size;
+ uint32_t write_buffer_size;
+ uint32_t write_max;
+ uint32_t block_size;
mutable bool read_eof;
mutable bool at_end;
@@ -57,7 +57,7 @@ class FileAccessCompressed : public FileAccess {
mutable int read_block_size;
mutable int read_pos;
Vector<ReadBlock> read_blocks;
- int read_total;
+ uint32_t read_total;
String magic;
mutable Vector<uint8_t> buffer;
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index cf82d04ac5..12503f3be4 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -73,14 +73,14 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
length = p_base->get_64();
base = p_base->get_pos();
ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT);
- int ds = length;
+ uint32_t ds = length;
if (ds % 16) {
ds += 16 - (ds % 16);
}
data.resize(ds);
- int blen = p_base->get_buffer(data.ptr(), ds);
+ uint32_t blen = p_base->get_buffer(data.ptr(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
aes256_context ctx;
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index 3df2806a7a..74d00a5a8f 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -48,7 +48,7 @@ private:
size_t base;
size_t length;
Vector<uint8_t> data;
- mutable size_t pos;
+ mutable int pos;
mutable bool eofed;
public:
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index be31076557..d8b8c8c200 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -244,14 +244,14 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
memdelete(sem);
}
-void FileAccessNetwork::_set_block(size_t p_offset, const Vector<uint8_t> &p_block) {
+void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) {
int page = p_offset / page_size;
ERR_FAIL_INDEX(page, pages.size());
if (page < pages.size() - 1) {
ERR_FAIL_COND(p_block.size() != page_size);
} else {
- ERR_FAIL_COND((p_block.size() != (total_size % page_size)));
+ ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size)));
}
buffer_mutex->lock();
diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h
index d6010cdbac..cd5046f007 100644
--- a/core/io/file_access_network.h
+++ b/core/io/file_access_network.h
@@ -97,7 +97,7 @@ class FileAccessNetwork : public FileAccess {
mutable int last_page;
mutable uint8_t *last_page_buff;
- uint32_t page_size;
+ int page_size;
int read_ahead;
int max_pages;
@@ -121,7 +121,7 @@ class FileAccessNetwork : public FileAccess {
friend class FileAccessNetworkClient;
void _queue_page(int p_page) const;
void _respond(size_t p_len, Error p_status);
- void _set_block(size_t p_offset, const Vector<uint8_t> &p_block);
+ void _set_block(int p_offset, const Vector<uint8_t> &p_block);
public:
enum Command {
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index af7db904e9..0834d6c321 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -333,14 +333,14 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
len -= 12;
buf += 12;
- int total = namecount + subnamecount;
+ uint32_t total = namecount + subnamecount;
if (flags & 2)
total++;
if (r_len)
(*r_len) += 12;
- for (int i = 0; i < total; i++) {
+ for (uint32_t i = 0; i < total; i++) {
ERR_FAIL_COND_V((int)len < 4, ERR_INVALID_DATA);
strlen = decode_uint32(buf);
@@ -566,7 +566,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (count) {
data.resize(count);
PoolVector<uint8_t>::Write w = data.write();
- for (int i = 0; i < count; i++) {
+ for (uint32_t i = 0; i < count; i++) {
w[i] = buf[i];
}
@@ -597,7 +597,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
//const int*rbuf=(const int*)buf;
data.resize(count);
PoolVector<int>::Write w = data.write();
- for (int i = 0; i < count; i++) {
+ for (uint32_t i = 0; i < count; i++) {
w[i] = decode_uint32(&buf[i * 4]);
}
@@ -624,7 +624,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
//const float*rbuf=(const float*)buf;
data.resize(count);
PoolVector<float>::Write w = data.write();
- for (int i = 0; i < count; i++) {
+ for (uint32_t i = 0; i < count; i++) {
w[i] = decode_float(&buf[i * 4]);
}
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 965d11e414..084d8ffcab 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -102,7 +102,7 @@ StringName ResourceInteractiveLoaderBinary::_get_string() {
uint32_t id = f->get_32();
if (id & 0x80000000) {
- uint32_t len = id & 0x7FFFFFFF;
+ int len = id & 0x7FFFFFFF;
if (len > str_buf.size()) {
str_buf.resize(len);
}
@@ -336,9 +336,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
} break;
case OBJECT_EXTERNAL_RESOURCE_INDEX: {
//new file format, just refers to an index in the external list
- uint32_t erindex = f->get_32();
+ int erindex = f->get_32();
- if (erindex >= external_resources.size()) {
+ if (erindex < 0 || erindex >= external_resources.size()) {
WARN_PRINT("Broken external resource! (index out of size");
r_v = Variant();
} else {
@@ -878,7 +878,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
f->close();
- ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a a new engine version: " + local_path);
+ ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path);
ERR_FAIL();
}
@@ -1005,7 +1005,7 @@ ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
memdelete(f);
}
-Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, Error *r_error) {
+Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
@@ -1019,7 +1019,8 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(cons
}
Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ String path = p_original_path != "" ? p_original_path : p_path;
+ ria->local_path = ProjectSettings::get_singleton()->localize_path(path);
ria->res_path = ria->local_path;
//ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
ria->open(f);
@@ -1116,6 +1117,9 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
memdelete(f);
}
ERR_FAIL_COND_V(!fw, ERR_CANT_CREATE);
+
+ uint8_t magic[4] = { 'R', 'S', 'R', 'C' };
+ fw->store_buffer(magic, 4);
}
bool big_endian = f->get_32();
@@ -1177,7 +1181,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
memdelete(f);
memdelete(fw);
- ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a a new engine version: " + local_path);
+ ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path);
ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
}
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 1bd0d333c6..ab77c2c9d3 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -101,7 +101,7 @@ public:
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
- virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
+ virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp
index 5a4f29fe67..be486a86a3 100644
--- a/core/io/resource_import.cpp
+++ b/core/io/resource_import.cpp
@@ -32,13 +32,17 @@
#include "os/os.h"
#include "variant_parser.h"
-Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type) const {
+Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const {
Error err;
FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
- if (!f)
+ if (!f) {
+ if (r_valid) {
+ *r_valid = false;
+ }
return err;
+ }
VariantParser::StreamFile stream;
stream.f = f;
@@ -47,6 +51,10 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
Variant value;
VariantParser::Tag next_tag;
+ if (r_valid) {
+ *r_valid = true;
+ }
+
int lines = 0;
String error_text;
bool path_found = false; //first match must have priority
@@ -79,6 +87,10 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
path_found = true; //first match must have priority
} else if (assign == "type") {
r_path_and_type.type = value;
+ } else if (assign == "valid") {
+ if (r_valid) {
+ *r_valid = value;
+ }
}
} else if (next_tag.name != "remap") {
@@ -107,7 +119,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_
return RES();
}
- RES res = ResourceLoader::load(pat.path, pat.type, false, r_error);
+ RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error);
#ifdef TOOLS_ENABLED
if (res.is_valid()) {
@@ -245,6 +257,14 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
memdelete(f);
}
+bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
+
+ bool valid = true;
+ PathAndType pat;
+ _get_path_and_type(p_path, pat, &valid);
+ return valid;
+}
+
String ResourceFormatImporter::get_resource_type(const String &p_path) const {
PathAndType pat;
diff --git a/core/io/resource_import.h b/core/io/resource_import.h
index bf0bf3987a..b10255fbab 100644
--- a/core/io/resource_import.h
+++ b/core/io/resource_import.h
@@ -40,7 +40,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
String type;
};
- Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type) const;
+ Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const;
static ResourceFormatImporter *singleton;
@@ -54,6 +54,7 @@ public:
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
+ virtual bool is_import_valid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual bool can_be_imported(const String &p_path) const;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index f0e804e2fa..4f266df43e 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -109,10 +109,10 @@ public:
ResourceInteractiveLoaderDefault() {}
};
-Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) {
+Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
//either this
- Ref<Resource> res = load(p_path, p_path, r_error);
+ Ref<Resource> res = load(p_path, p_original_path, r_error);
if (res.is_null())
return Ref<ResourceInteractiveLoader>();
@@ -126,7 +126,7 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
String path = p_path;
//or this must be implemented
- Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, r_error);
+ Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, p_original_path, r_error);
if (!ril.is_valid())
return RES();
ril->set_local_path(p_original_path);
@@ -157,6 +157,34 @@ void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *
///////////////////////////////////
+RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
+
+ bool found = false;
+
+ // Try all loaders and pick the first match for the type hint
+ for (int i = 0; i < loader_count; i++) {
+
+ if (!loader[i]->recognize_path(p_path, p_type_hint)) {
+ continue;
+ }
+ found = true;
+ RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error);
+ if (res.is_null()) {
+ continue;
+ }
+
+ return res;
+ }
+
+ if (found) {
+ ERR_EXPLAIN("Failed loading resource: " + p_path);
+ } else {
+ ERR_EXPLAIN("No loader found for resource: " + p_path);
+ }
+ ERR_FAIL_V(RES());
+ return RES();
+}
+
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
if (r_error)
@@ -183,45 +211,29 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
if (OS::get_singleton()->is_stdout_verbose())
print_line("load resource: " + path);
- bool found = false;
- // Try all loaders and pick the first match for the type hint
- for (int i = 0; i < loader_count; i++) {
+ RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error);
- if (!loader[i]->recognize_path(path, p_type_hint)) {
- continue;
- }
- found = true;
- RES res = loader[i]->load(path, path, r_error);
- if (res.is_null()) {
- continue;
- }
- if (!p_no_cache)
- res->set_path(local_path);
+ if (res.is_null()) {
+ return RES();
+ }
+ if (!p_no_cache)
+ res->set_path(local_path);
- if (xl_remapped)
- res->set_as_translation_remapped(true);
+ if (xl_remapped)
+ res->set_as_translation_remapped(true);
#ifdef TOOLS_ENABLED
- res->set_edited(false);
- if (timestamp_on_load) {
- uint64_t mt = FileAccess::get_modified_time(path);
- //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt);
- res->set_last_modified_time(mt);
- }
-#endif
-
- return res;
+ res->set_edited(false);
+ if (timestamp_on_load) {
+ uint64_t mt = FileAccess::get_modified_time(path);
+ //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt);
+ res->set_last_modified_time(mt);
}
+#endif
- if (found) {
- ERR_EXPLAIN("Failed loading resource: " + path);
- } else {
- ERR_EXPLAIN("No loader found for resource: " + path);
- }
- ERR_FAIL_V(RES());
- return RES();
+ return res;
}
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
@@ -262,7 +274,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
if (!loader[i]->recognize_path(path, p_type_hint))
continue;
found = true;
- Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, r_error);
+ Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error);
if (ril.is_null())
continue;
if (!p_no_cache)
@@ -296,6 +308,31 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l
}
}
+bool ResourceLoader::is_import_valid(const String &p_path) {
+
+ String path = _path_remap(p_path);
+
+ String local_path;
+ if (path.is_rel_path())
+ local_path = "res://" + path;
+ else
+ local_path = ProjectSettings::get_singleton()->localize_path(path);
+
+ for (int i = 0; i < loader_count; i++) {
+
+ if (!loader[i]->recognize_path(local_path))
+ continue;
+ /*
+ if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
+ continue;
+ */
+
+ return loader[i]->is_import_valid(p_path);
+ }
+
+ return false; //not found
+}
+
void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
String path = _path_remap(p_path);
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 9e059c2977..a71a568569 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -57,7 +57,7 @@ public:
class ResourceFormatLoader {
public:
- virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
+ virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
@@ -66,6 +66,7 @@ public:
virtual String get_resource_type(const String &p_path) const = 0;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map) { return OK; }
+ virtual bool is_import_valid(const String &p_path) const { return true; }
virtual ~ResourceFormatLoader() {}
};
@@ -95,6 +96,10 @@ class ResourceLoader {
static SelfList<Resource>::List remapped_list;
+ friend class ResourceFormatImporter;
+ //internal load function
+ static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error);
+
public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
@@ -104,6 +109,7 @@ public:
static String get_resource_type(const String &p_path);
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
+ static bool is_import_valid(const String &p_path);
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; }
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 353eabea45..92af247823 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -51,8 +51,8 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
Ref<Translation> translation = Ref<Translation>(memnew(Translation));
int line = 1;
- bool skip_this;
- bool skip_next;
+ bool skip_this = false;
+ bool skip_next = false;
while (true) {
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 62110bfe24..3a4be7cd13 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -385,7 +385,7 @@ void XMLParser::_bind_methods() {
Error XMLParser::read() {
// if not end reached, parse the node
- if (P && (P - data) < length - 1 && *P != 0) {
+ if (P && (P - data) < (int64_t)length - 1 && *P != 0) {
_parse_current_node();
return OK;
}
diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h
index 28c57b567f..26616ed94a 100644
--- a/core/io/xml_parser.h
+++ b/core/io/xml_parser.h
@@ -67,7 +67,7 @@ public:
private:
char *data;
char *P;
- int length;
+ uint64_t length;
void unescape(String &p_str);
Vector<String> special_characters;
String node_name;
diff --git a/core/list.h b/core/list.h
index 0cad6038ff..a67287a9ab 100644
--- a/core/list.h
+++ b/core/list.h
@@ -180,7 +180,7 @@ private:
public:
/**
- * return an const iterator to the beginning of the list.
+ * return a const iterator to the beginning of the list.
*/
_FORCE_INLINE_ const Element *front() const {
@@ -195,7 +195,7 @@ public:
};
/**
- * return an const iterator to the last member of the list.
+ * return a const iterator to the last member of the list.
*/
_FORCE_INLINE_ const Element *back() const {
diff --git a/core/math/a_star.h b/core/math/a_star.h
index d2d2166719..75b860d0a4 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* a_star.h */
+/* a_star.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index 748faad28f..e1b172e491 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -296,7 +296,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V
/** FIND SUPPORT VERTEX **/
int vert_support_idx = -1;
- real_t support_max;
+ real_t support_max = 0;
for (int i = 0; i < 3; i++) {
diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp
index c7e2a8f307..4051de7afb 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/matrix3.cpp
@@ -107,6 +107,13 @@ bool Basis::is_orthogonal() const {
return is_equal_approx(id, m);
}
+bool Basis::is_diagonal() const {
+ return (
+ Math::is_equal_approx(elements[0][1], 0) && Math::is_equal_approx(elements[0][2], 0) &&
+ Math::is_equal_approx(elements[1][0], 0) && Math::is_equal_approx(elements[1][2], 0) &&
+ Math::is_equal_approx(elements[2][0], 0) && Math::is_equal_approx(elements[2][1], 0));
+}
+
bool Basis::is_rotation() const {
return Math::is_equal_approx(determinant(), 1) && is_orthogonal();
}
@@ -227,7 +234,22 @@ Basis Basis::scaled(const Vector3 &p_scale) const {
return m;
}
+void Basis::set_scale(const Vector3 &p_scale) {
+
+ set_axis(0, get_axis(0).normalized() * p_scale.x);
+ set_axis(1, get_axis(1).normalized() * p_scale.y);
+ set_axis(2, get_axis(2).normalized() * p_scale.z);
+}
+
Vector3 Basis::get_scale() const {
+
+ return Vector3(
+ Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
+ Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
+ Vector3(elements[0][2], elements[1][2], elements[2][2]).length());
+}
+
+Vector3 Basis::get_signed_scale() const {
// FIXME: We are assuming M = R.S (R is rotation and S is scaling), and use polar decomposition to extract R and S.
// A polar decomposition is M = O.P, where O is an orthogonal matrix (meaning rotation and reflection) and
// P is a positive semi-definite matrix (meaning it contains absolute values of scaling along its diagonal).
@@ -241,12 +263,13 @@ Vector3 Basis::get_scale() const {
// This may lead to confusion for some users though.
//
// The convention we use here is to absorb the sign flip into the scaling matrix.
- // The same convention is also used in other similar functions such as set_scale,
- // get_rotation_axis_angle, get_rotation, set_rotation_axis_angle, set_rotation_euler, ...
+ // The same convention is also used in other similar functions such as get_rotation_axis_angle, get_rotation, ...
//
// A proper way to get rid of this issue would be to store the scaling values (or at least their signs)
// as a part of Basis. However, if we go that path, we need to disable direct (write) access to the
// matrix elements.
+ //
+ // The rotation part of this decomposition is returned by get_rotation* functions.
real_t det_sign = determinant() > 0 ? 1 : -1;
return det_sign * Vector3(
Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
@@ -254,15 +277,24 @@ Vector3 Basis::get_scale() const {
Vector3(elements[0][2], elements[1][2], elements[2][2]).length());
}
-// Sets scaling while preserving rotation.
-// This requires some care when working with matrices with negative determinant,
-// since we're using a particular convention for "polar" decomposition in get_scale and get_rotation.
-// For details, see the explanation in get_scale.
-void Basis::set_scale(const Vector3 &p_scale) {
- Vector3 e = get_euler();
- Basis(); // reset to identity
- scale(p_scale);
- rotate(e);
+// Decomposes a Basis into a rotation-reflection matrix (an element of the group O(3)) and a positive scaling matrix as B = O.S.
+// Returns the rotation-reflection matrix via reference argument, and scaling information is returned as a Vector3.
+// This (internal) function is too specıfıc and named too ugly to expose to users, and probably there's no need to do so.
+Vector3 Basis::rotref_posscale_decomposition(Basis &rotref) const {
+#ifdef MATH_CHECKS
+ ERR_FAIL_COND_V(determinant() == 0, Vector3());
+
+ Basis m = transposed() * (*this);
+ ERR_FAIL_COND_V(m.is_diagonal() == false, Vector3());
+#endif
+ Vector3 scale = get_scale();
+ Basis inv_scale = Basis().scaled(scale.inverse()); // this will also absorb the sign of scale
+ rotref = (*this) * inv_scale;
+
+#ifdef MATH_CHECKS
+ ERR_FAIL_COND_V(rotref.is_orthogonal() == false, Vector3());
+#endif
+ return scale.abs();
}
// Multiplies the matrix from left by the rotation matrix: M -> R.M
@@ -316,28 +348,6 @@ void Basis::get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const {
m.get_axis_angle(p_axis, p_angle);
}
-// Sets rotation while preserving scaling.
-// This requires some care when working with matrices with negative determinant,
-// since we're using a particular convention for "polar" decomposition in get_scale and get_rotation.
-// For details, see the explanation in get_scale.
-void Basis::set_rotation_euler(const Vector3 &p_euler) {
- Vector3 s = get_scale();
- Basis(); // reset to identity
- scale(s);
- rotate(p_euler);
-}
-
-// Sets rotation while preserving scaling.
-// This requires some care when working with matrices with negative determinant,
-// since we're using a particular convention for "polar" decomposition in get_scale and get_rotation.
-// For details, see the explanation in get_scale.
-void Basis::set_rotation_axis_angle(const Vector3 &p_axis, real_t p_angle) {
- Vector3 s = get_scale();
- Basis(); // reset to identity
- scale(s);
- rotate(p_axis, p_angle);
-}
-
// get_euler_xyz returns a vector containing the Euler angles in the format
// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last
// (following the convention they are commonly defined in the literature).
@@ -364,8 +374,9 @@ Vector3 Basis::get_euler_xyz() const {
euler.y = Math::asin(elements[0][2]);
if (euler.y < Math_PI * 0.5) {
if (euler.y > -Math_PI * 0.5) {
- //if rotation is Y-only, return a proper -pi,pi range like in x or z for the same case.
+ // is this a pure Y rotation?
if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) {
+ // return the simplest form
euler.x = 0;
euler.y = atan2(elements[0][2], elements[0][0]);
euler.z = 0;
@@ -432,7 +443,9 @@ Vector3 Basis::get_euler_yxz() const {
if (m12 < 1) {
if (m12 > -1) {
- if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) { // use pure x rotation
+ // is this a pure X rotation?
+ if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) {
+ // return the simplest form
euler.x = atan2(-m12, elements[1][1]);
euler.y = 0;
euler.z = 0;
diff --git a/core/math/matrix3.h b/core/math/matrix3.h
index be85c244bd..23429888e0 100644
--- a/core/math/matrix3.h
+++ b/core/math/matrix3.h
@@ -81,8 +81,7 @@ public:
Vector3 get_rotation() const;
void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const;
- void set_rotation_euler(const Vector3 &p_euler);
- void set_rotation_axis_angle(const Vector3 &p_axis, real_t p_angle);
+ Vector3 rotref_posscale_decomposition(Basis &rotref) const;
Vector3 get_euler_xyz() const;
void set_euler_xyz(const Vector3 &p_euler);
@@ -98,8 +97,9 @@ public:
void scale(const Vector3 &p_scale);
Basis scaled(const Vector3 &p_scale) const;
- Vector3 get_scale() const;
void set_scale(const Vector3 &p_scale);
+ Vector3 get_scale() const;
+ Vector3 get_signed_scale() const;
// transposed dot products
_FORCE_INLINE_ real_t tdotx(const Vector3 &v) const {
@@ -132,6 +132,7 @@ public:
void set_orthogonal_index(int p_index);
bool is_orthogonal() const;
+ bool is_diagonal() const;
bool is_rotation() const;
operator String() const;
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index e9a383df40..e0137b6921 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -76,7 +76,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
int simplex[4];
{
- real_t max, min;
+ real_t max = 0, min = 0;
for (int i = 0; i < p_points.size(); i++) {
@@ -99,7 +99,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//third vertex is one most further away from the line
{
- real_t maxd;
+ real_t maxd = 0;
Vector3 rel12 = p_points[simplex[0]] - p_points[simplex[1]];
for (int i = 0; i < p_points.size(); i++) {
@@ -121,7 +121,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//fourth vertex is the one most further away from the plane
{
- real_t maxd;
+ real_t maxd = 0;
Plane p(p_points[simplex[0]], p_points[simplex[1]], p_points[simplex[2]]);
for (int i = 0; i < p_points.size(); i++) {
@@ -389,8 +389,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
for (int i = 0; i < f.indices.size(); i++) {
- uint32_t a = E->get().indices[i];
- uint32_t b = E->get().indices[(i + 1) % f.indices.size()];
+ int a = E->get().indices[i];
+ int b = E->get().indices[(i + 1) % f.indices.size()];
Edge e(a, b);
Map<Edge, RetFaceConnect>::Element *F = ret_edges.find(e);
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 60df69a509..638a39ab73 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -118,17 +118,17 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c)
/* not sure if very "efficient" but good enough? */
- Vector3 src_scale = basis.get_scale();
- Quat src_rot = basis;
+ Vector3 src_scale = basis.get_signed_scale();
+ Quat src_rot = basis.orthonormalized();
Vector3 src_loc = origin;
- Vector3 dst_scale = p_transform.basis.get_scale();
+ Vector3 dst_scale = p_transform.basis.get_signed_scale();
Quat dst_rot = p_transform.basis;
Vector3 dst_loc = p_transform.origin;
- Transform dst;
- dst.basis = src_rot.slerp(dst_rot, p_c);
- dst.basis.scale(src_scale.linear_interpolate(dst_scale, p_c));
+ Transform dst; //this could be made faster by using a single function in Basis..
+ dst.basis = src_rot.slerp(dst_rot, p_c).normalized();
+ dst.basis.set_scale(src_scale.linear_interpolate(dst_scale, p_c));
dst.origin = src_loc.linear_interpolate(dst_loc, p_c);
return dst;
diff --git a/core/method_bind.h b/core/method_bind.h
index f6cae6f34d..3c43f86b54 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -334,6 +334,7 @@ public:
}
argument_types = at;
arguments = p_info;
+ arguments.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
#endif
}
@@ -368,7 +369,7 @@ MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, i
// tale of an amazing hack.. //
-// if you declare an nonexistent class..
+// if you declare a nonexistent class..
class __UnexistingClass;
#include "method_bind.gen.inc"
diff --git a/core/object.cpp b/core/object.cpp
index b220dc0563..23e32a214a 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -274,6 +274,63 @@ MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyIn
arguments.push_back(p_param5);
}
+MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name)
+ : name(p_name),
+ flags(METHOD_FLAG_NORMAL),
+ id(0) {
+ return_val = p_ret;
+}
+
+MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1)
+ : name(p_name),
+ flags(METHOD_FLAG_NORMAL),
+ id(0) {
+ return_val = p_ret;
+ arguments.push_back(p_param1);
+}
+
+MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2)
+ : name(p_name),
+ flags(METHOD_FLAG_NORMAL),
+ id(0) {
+ return_val = p_ret;
+ arguments.push_back(p_param1);
+ arguments.push_back(p_param2);
+}
+
+MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3)
+ : name(p_name),
+ flags(METHOD_FLAG_NORMAL),
+ id(0) {
+ return_val = p_ret;
+ arguments.push_back(p_param1);
+ arguments.push_back(p_param2);
+ arguments.push_back(p_param3);
+}
+
+MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4)
+ : name(p_name),
+ flags(METHOD_FLAG_NORMAL),
+ id(0) {
+ return_val = p_ret;
+ arguments.push_back(p_param1);
+ arguments.push_back(p_param2);
+ arguments.push_back(p_param3);
+ arguments.push_back(p_param4);
+}
+
+MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5)
+ : name(p_name),
+ flags(METHOD_FLAG_NORMAL),
+ id(0) {
+ return_val = p_ret;
+ arguments.push_back(p_param1);
+ arguments.push_back(p_param2);
+ arguments.push_back(p_param3);
+ arguments.push_back(p_param4);
+ arguments.push_back(p_param5);
+}
+
Object::Connection::operator Variant() const {
Dictionary d;
@@ -1529,7 +1586,7 @@ void Object::_bind_methods() {
ADD_SIGNAL(MethodInfo("script_changed"));
BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
- BIND_VMETHOD(MethodInfo("_set:bool", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value")));
#ifdef TOOLS_ENABLED
MethodInfo miget("_get", PropertyInfo(Variant::STRING, "property"));
miget.return_val.name = "Variant";
diff --git a/core/object.h b/core/object.h
index 8b13477480..6e1ed4308e 100644
--- a/core/object.h
+++ b/core/object.h
@@ -205,6 +205,12 @@ struct MethodInfo {
MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3);
MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4);
MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5);
+ MethodInfo(const PropertyInfo &p_ret, const String &p_name);
+ MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1);
+ MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2);
+ MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3);
+ MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4);
+ MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5);
};
// old cast_to
diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h
new file mode 100644
index 0000000000..3e619d2b2e
--- /dev/null
+++ b/core/ordered_hash_map.h
@@ -0,0 +1,315 @@
+/*************************************************************************/
+/* ordered_hash_map.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef ORDERED_HASH_MAP_H
+#define ORDERED_HASH_MAP_H
+
+#include "hash_map.h"
+#include "list.h"
+#include "pair.h"
+
+/**
+ * A hash map which allows to iterate elements in insertion order.
+ * Insertion, lookup, deletion have O(1) complexity.
+ * The API aims to be consistent with Map rather than HashMap, because the
+ * former is more frequently used and is more coherent with the rest of the
+ * codebase.
+ * Deletion during iteration is safe and will preserve the order.
+ */
+template <class K, class V, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<K>, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8>
+class OrderedHashMap {
+ typedef List<Pair<const K *, V> > InternalList;
+ typedef HashMap<K, typename InternalList::Element *, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP> InternalMap;
+
+ InternalList list;
+ InternalMap map;
+
+public:
+ class Element {
+ friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
+
+ typename InternalList::Element *list_element;
+ typename InternalList::Element *next_element;
+ typename InternalList::Element *prev_element;
+
+ Element(typename InternalList::Element *p_element) {
+ list_element = p_element;
+
+ if (list_element) {
+ next_element = list_element->next();
+ prev_element = list_element->prev();
+ }
+ }
+
+ public:
+ _FORCE_INLINE_ Element()
+ : list_element(NULL), next_element(NULL), prev_element(NULL) {
+ }
+
+ Element next() const {
+ return Element(next_element);
+ }
+
+ Element prev() const {
+ return Element(prev_element);
+ }
+
+ Element(const Element &other)
+ : list_element(other.list_element),
+ prev_element(other.prev_element),
+ next_element(other.next_element) {
+ }
+
+ Element &operator=(const Element &other) {
+ list_element = other.list_element;
+ next_element = other.next_element;
+ prev_element = other.prev_element;
+ return *this;
+ }
+
+ friend bool operator==(const Element &, const Element &);
+ friend bool operator!=(const Element &, const Element &);
+
+ operator bool() const {
+ return (list_element != NULL);
+ }
+
+ const K &key() const {
+ CRASH_COND(!list_element);
+ return *(list_element->get().first);
+ };
+
+ V &value() {
+ CRASH_COND(!list_element);
+ return list_element->get().second;
+ };
+
+ const V &value() const {
+ CRASH_COND(!list_element);
+ return list_element->get().second;
+ };
+
+ V &get() {
+ CRASH_COND(!list_element);
+ return list_element->get().second;
+ };
+
+ const V &get() const {
+ CRASH_COND(!list_element);
+ return list_element->get().second;
+ };
+ };
+
+ class ConstElement {
+ friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
+
+ const typename InternalList::Element *list_element;
+
+ ConstElement(const typename InternalList::Element *p_element)
+ : list_element(p_element) {
+ }
+
+ public:
+ _FORCE_INLINE_ ConstElement()
+ : list_element(NULL) {
+ }
+
+ ConstElement(const ConstElement &other)
+ : list_element(other.list_element) {
+ }
+
+ ConstElement &operator=(const ConstElement &other) {
+ list_element = other.list_element;
+ return *this;
+ }
+
+ ConstElement next() const {
+ return ConstElement(list_element ? list_element->next() : NULL);
+ }
+
+ ConstElement prev() const {
+ return ConstElement(list_element ? list_element->prev() : NULL);
+ }
+
+ friend bool operator==(const ConstElement &, const ConstElement &);
+ friend bool operator!=(const ConstElement &, const ConstElement &);
+
+ operator bool() const {
+ return (list_element != NULL);
+ }
+
+ const K &key() const {
+ CRASH_COND(!list_element);
+ return *(list_element->get().first);
+ };
+
+ const V &value() const {
+ CRASH_COND(!list_element);
+ return list_element->get().second;
+ };
+
+ const V &get() const {
+ CRASH_COND(!list_element);
+ return list_element->get().second;
+ };
+ };
+
+ ConstElement find(const K &p_key) const {
+ typename InternalList::Element **list_element = map.getptr(p_key);
+ if (list_element) {
+ return ConstElement(*list_element);
+ }
+ return ConstElement(NULL);
+ }
+
+ Element find(const K &p_key) {
+ typename InternalList::Element **list_element = map.getptr(p_key);
+ if (list_element) {
+ return Element(*list_element);
+ }
+ return Element(NULL);
+ }
+
+ Element insert(const K &p_key, const V &p_value) {
+ typename InternalList::Element **list_element = map.getptr(p_key);
+ if (list_element) {
+ (*list_element)->get().second = p_value;
+ return Element(*list_element);
+ }
+ typename InternalList::Element *new_element = list.push_back(Pair<const K *, V>(NULL, p_value));
+ typename InternalMap::Element *e = map.set(p_key, new_element);
+ new_element->get().first = &e->key();
+
+ return Element(new_element);
+ }
+
+ void erase(Element &p_element) {
+ map.erase(p_element.key());
+ list.erase(p_element.list_element);
+ p_element.list_element = NULL;
+ }
+
+ bool erase(const K &p_key) {
+ typename InternalList::Element **list_element = map.getptr(p_key);
+ if (list_element) {
+ list.erase(*list_element);
+ map.erase(p_key);
+ return true;
+ }
+ return false;
+ }
+
+ inline bool has(const K &p_key) const {
+ return map.has(p_key);
+ }
+
+ const V &operator[](const K &p_key) const {
+ ConstElement e = find(p_key);
+ CRASH_COND(!e);
+ return e.value();
+ }
+
+ V &operator[](const K &p_key) {
+ Element e = find(p_key);
+ if (!e) {
+ // consistent with Map behaviour
+ e = insert(p_key, V());
+ }
+ return e.value();
+ }
+
+ inline Element front() {
+ return Element(list.front());
+ }
+
+ inline Element back() {
+ return Element(list.back());
+ }
+
+ inline ConstElement front() const {
+ return ConstElement(list.front());
+ }
+
+ inline ConstElement back() const {
+ return ConstElement(list.back());
+ }
+
+ inline bool empty() const { return list.empty(); }
+ inline int size() const { return list.size(); }
+
+ void clear() {
+ map.clear();
+ list.clear();
+ }
+
+private:
+ void _copy_from(const OrderedHashMap &p_map) {
+ for (ConstElement E = p_map.front(); E; E = E.next()) {
+ insert(E.key(), E.value());
+ }
+ }
+
+public:
+ void operator=(const OrderedHashMap &p_map) {
+ _copy_from(p_map);
+ }
+
+ OrderedHashMap(const OrderedHashMap &p_map) {
+ _copy_from(p_map);
+ }
+
+ _FORCE_INLINE_ OrderedHashMap() {
+ }
+};
+
+template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP>
+bool operator==(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &first,
+ const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &second) {
+ return (first.list_element == second.list_element);
+}
+
+template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP>
+bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &first,
+ const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &second) {
+ return (first.list_element != second.list_element);
+}
+
+template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP>
+bool operator==(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &first,
+ const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &second) {
+ return (first.list_element == second.list_element);
+}
+
+template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP>
+bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &first,
+ const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &second) {
+ return (first.list_element != second.list_element);
+}
+
+#endif // ORDERED_HASH_MAP_H \ No newline at end of file
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 1292b7eeed..764f7fe6e6 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -64,12 +64,13 @@ void OS::debug_break(){
void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
- const char *err_type;
+ const char *err_type = "**ERROR**";
switch (p_type) {
case ERR_ERROR: err_type = "**ERROR**"; break;
case ERR_WARNING: err_type = "**WARNING**"; break;
case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break;
case ERR_SHADER: err_type = "**SHADER ERROR**"; break;
+ default: ERR_PRINT("Unknown error type"); break;
}
if (p_rationale && *p_rationale)
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index 4040680c6d..ad8438e416 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -61,7 +61,7 @@ Variant PackedDataContainer::_iter_init_ofs(const Array &p_iter, uint32_t p_offs
Variant PackedDataContainer::_iter_next_ofs(const Array &p_iter, uint32_t p_offset) {
Array ref = p_iter;
- uint32_t size = _size(p_offset);
+ int size = _size(p_offset);
if (ref.size() != 1)
return false;
int pos = ref[0];
@@ -74,7 +74,7 @@ Variant PackedDataContainer::_iter_next_ofs(const Array &p_iter, uint32_t p_offs
Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_offset) {
- uint32_t size = _size(p_offset);
+ int size = _size(p_offset);
int pos = p_iter;
if (pos < 0 || pos >= size)
return Variant();
@@ -164,7 +164,7 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b
if (p_key.is_num()) {
int idx = p_key;
- uint32_t len = decode_uint32(r + 4);
+ int len = decode_uint32(r + 4);
if (idx < 0 || idx >= len) {
err = true;
return Variant();
@@ -183,7 +183,7 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b
uint32_t len = decode_uint32(r + 4);
bool found = false;
- for (int i = 0; i < len; i++) {
+ for (uint32_t i = 0; i < len; i++) {
uint32_t khash = decode_uint32(r + 8 + i * 12 + 0);
if (khash == hash) {
Variant key = _get_at_ofs(decode_uint32(r + 8 + i * 12 + 4), rd.ptr(), err);
diff --git a/core/pair.h b/core/pair.h
index f780c79c81..535c3355b6 100644
--- a/core/pair.h
+++ b/core/pair.h
@@ -44,6 +44,16 @@ struct Pair {
};
template <class F, class S>
+bool operator==(const Pair<F, S> &pair, const Pair<F, S> &other) {
+ return (pair.first == other.first) && (pair.second == other.second);
+}
+
+template <class F, class S>
+bool operator!=(const Pair<F, S> &pair, const Pair<F, S> &other) {
+ return (pair.first != other.first) || (pair.second != other.second);
+}
+
+template <class F, class S>
struct PairSort {
bool operator()(const Pair<F, S> &A, const Pair<F, S> &B) const {
diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp
index c122d21545..c5f6d0dde0 100644
--- a/core/pool_allocator.cpp
+++ b/core/pool_allocator.cpp
@@ -339,9 +339,9 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
ERR_FAIL_COND_V(e->lock, ERR_ALREADY_IN_USE);
}
- int alloc_size = aligned(p_new_size);
+ uint32_t alloc_size = aligned(p_new_size);
- if (aligned(e->len) == alloc_size) {
+ if ((uint32_t)aligned(e->len) == alloc_size) {
e->len = p_new_size;
mt_unlock();
@@ -374,7 +374,7 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
}
//no need to move stuff around, it fits before the next block
- int next_pos;
+ uint32_t next_pos;
if (entry_indices_pos + 1 == entry_count) {
next_pos = pool_size; // - static_area_size;
} else {
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index ce1d7918db..a74917162b 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* globals.cpp */
+/* project_settings.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/core/project_settings.h b/core/project_settings.h
index 5c8907c74e..718ab2a011 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* globals.h */
+/* project_settings.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/core/reference.h b/core/reference.h
index 5fe8296314..ca3ae60418 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -62,7 +62,7 @@ public:
template <class T>
class Ref {
- T *reference;
+ T *reference = NULL;
void ref(const Ref &p_from) {
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 9a891f9e52..bde80a30bc 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -54,6 +54,11 @@ void Script::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_source_code"), &Script::get_source_code);
ClassDB::bind_method(D_METHOD("set_source_code", "source"), &Script::set_source_code);
ClassDB::bind_method(D_METHOD("reload", "keep_state"), &Script::reload, DEFVAL(false));
+
+ ClassDB::bind_method(D_METHOD("has_script_signal", "signal_name"), &Script::has_script_signal);
+
+ ClassDB::bind_method(D_METHOD("is_tool"), &Script::is_tool);
+ ClassDB::bind_method(D_METHOD("get_node_type"), &Script::get_node_type);
}
void ScriptServer::set_scripting_enabled(bool p_enabled) {
diff --git a/core/script_language.h b/core/script_language.h
index 342d8c8072..2261737f9a 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -206,6 +206,7 @@ public:
virtual int find_function(const String &p_function, const String &p_code) const = 0;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const = 0;
virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; }
+ virtual bool overrides_external_editor() { return false; }
virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; }
diff --git a/core/type_info.h b/core/type_info.h
index a7d3fa20c8..da6047450c 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -51,15 +51,15 @@ struct GetTypeInfo {
template <> \
struct GetTypeInfo<m_type> { \
enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
} \
}; \
template <> \
struct GetTypeInfo<const m_type &> { \
enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
} \
};
@@ -110,49 +110,47 @@ template <>
struct GetTypeInfo<RefPtr> {
enum { VARIANT_TYPE = Variant::OBJECT };
static inline PropertyInfo get_class_info() {
- return PropertyInfo(Variant::OBJECT,String(),PROPERTY_HINT_RESOURCE_TYPE,"Reference");
+ return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
}
};
template <>
struct GetTypeInfo<const RefPtr &> {
enum { VARIANT_TYPE = Variant::OBJECT };
static inline PropertyInfo get_class_info() {
- return PropertyInfo(Variant::OBJECT,String(),PROPERTY_HINT_RESOURCE_TYPE,"Reference");
+ return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
}
};
-
//for variant
-template<>
+template <>
struct GetTypeInfo<Variant> {
enum { VARIANT_TYPE = Variant::NIL };
static inline PropertyInfo get_class_info() {
- return PropertyInfo(Variant::NIL,String(),PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_NIL_IS_VARIANT);
+ return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
}
};
-template<>
-struct GetTypeInfo<const Variant&> {
+template <>
+struct GetTypeInfo<const Variant &> {
enum { VARIANT_TYPE = Variant::NIL };
static inline PropertyInfo get_class_info() {
- return PropertyInfo(Variant::NIL,String(),PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_NIL_IS_VARIANT);
+ return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
}
};
-
#define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \
template <> \
struct GetTypeInfo<m_template<m_type> > { \
enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
} \
}; \
template <> \
struct GetTypeInfo<const m_template<m_type> &> { \
enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
} \
};
@@ -178,7 +176,6 @@ struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type>
static inline PropertyInfo get_class_info() {
return PropertyInfo(StringName(T::get_class_static()));
}
-
};
template <typename T>
@@ -190,13 +187,13 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>:
}
};
-#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
- template <> \
- struct GetTypeInfo<m_impl> { \
- enum { VARIANT_TYPE = Variant::INT }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo(Variant::INT,String(),PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_CLASS_IS_ENUM,String(#m_enum).replace("::",".")); \
- } \
+#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
+ template <> \
+ struct GetTypeInfo<m_impl> { \
+ enum { VARIANT_TYPE = Variant::INT }; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, String(#m_enum).replace("::", ".")); \
+ } \
};
#define MAKE_ENUM_TYPE_INFO(m_enum) \
@@ -212,9 +209,15 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
return GetTypeInfo<T>::get_class_info().class_name;
}
+#define CLASS_INFO(m_type) \
+ (GetTypeInfo<m_type *>::VARIANT_TYPE != Variant::NIL ? \
+ GetTypeInfo<m_type *>::get_class_info() : \
+ GetTypeInfo<m_type>::get_class_info())
+
#else
#define MAKE_ENUM_TYPE_INFO(m_enum)
+#define CLASS_INFO(m_type)
#endif // DEBUG_METHODS_ENABLED
diff --git a/core/ustring.cpp b/core/ustring.cpp
index ee07c7b11b..8273ed144b 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -588,7 +588,7 @@ String String::camelcase_to_underscore(bool lowercase) const {
const char a = 'a', z = 'z';
int start_index = 0;
- for (size_t i = 1; i < this->size(); i++) {
+ for (int i = 1; i < this->size(); i++) {
bool is_upper = cstr[i] >= A && cstr[i] <= Z;
bool is_number = cstr[i] >= '0' && cstr[i] <= '9';
bool are_next_2_lower = false;
@@ -3655,12 +3655,12 @@ String String::sprintf(const Array &values, bool *error) const {
CharType *self = (CharType *)c_str();
bool in_format = false;
int value_index = 0;
- int min_chars;
- int min_decimals;
- bool in_decimals;
- bool pad_with_zeroes;
- bool left_justified;
- bool show_sign;
+ int min_chars = 0;
+ int min_decimals = 0;
+ bool in_decimals = false;
+ bool pad_with_zeroes = false;
+ bool left_justified = false;
+ bool show_sign = false;
*error = true;
@@ -3687,12 +3687,12 @@ String String::sprintf(const Array &values, bool *error) const {
}
int64_t value = values[value_index];
- int base;
+ int base = 16;
bool capitalize = false;
switch (c) {
case 'd': base = 10; break;
case 'o': base = 8; break;
- case 'x': base = 16; break;
+ case 'x': break;
case 'X':
base = 16;
capitalize = true;
@@ -3842,7 +3842,7 @@ String String::sprintf(const Array &values, bool *error) const {
}
break;
}
- case '.': { // Float separtor.
+ case '.': { // Float separator.
if (in_decimals) {
return "too many decimal points in format";
}
@@ -3851,7 +3851,7 @@ String String::sprintf(const Array &values, bool *error) const {
break;
}
- case '*': { // Dyanmic width, based on value.
+ case '*': { // Dynamic width, based on value.
if (value_index >= values.size()) {
return "not enough arguments for format string";
}
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 77372d1e60..ad15f8f5cb 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -729,9 +729,6 @@ struct _VariantCall {
VCALL_PTR1R(Basis, scaled);
VCALL_PTR0R(Basis, get_scale);
VCALL_PTR0R(Basis, get_euler);
- VCALL_PTR1(Basis, set_scale);
- VCALL_PTR1(Basis, set_rotation_euler);
- VCALL_PTR2(Basis, set_rotation_axis_angle);
VCALL_PTR1R(Basis, tdotx);
VCALL_PTR1R(Basis, tdoty);
VCALL_PTR1R(Basis, tdotz);
@@ -1700,9 +1697,6 @@ void register_variant_methods() {
ADDFUNC0(BASIS, REAL, Basis, determinant, varray());
ADDFUNC2(BASIS, BASIS, Basis, rotated, VECTOR3, "axis", REAL, "phi", varray());
ADDFUNC1(BASIS, BASIS, Basis, scaled, VECTOR3, "scale", varray());
- ADDFUNC1(BASIS, NIL, Basis, set_scale, VECTOR3, "scale", varray());
- ADDFUNC1(BASIS, NIL, Basis, set_rotation_euler, VECTOR3, "euler", varray());
- ADDFUNC2(BASIS, NIL, Basis, set_rotation_axis_angle, VECTOR3, "axis", REAL, "angle", varray());
ADDFUNC0(BASIS, VECTOR3, Basis, get_scale, varray());
ADDFUNC0(BASIS, VECTOR3, Basis, get_euler, varray());
ADDFUNC1(BASIS, REAL, Basis, tdotx, VECTOR3, "with", varray());
diff --git a/core/vmap.h b/core/vmap.h
index f0977341ec..8165a919b6 100644
--- a/core/vmap.h
+++ b/core/vmap.h
@@ -60,9 +60,13 @@ class VMap {
int low = 0;
int high = _data.size() - 1;
- int middle;
const _Pair *a = &_data[0];
+ int middle = 0;
+#if DEBUG_ENABLED
+ if (low > high)
+ ERR_PRINT("low > high, this may be a bug");
+#endif
while (low <= high) {
middle = (low + high) / 2;
diff --git a/core/vset.h b/core/vset.h
index 7b12ae0b25..67af6c1a4c 100644
--- a/core/vset.h
+++ b/core/vset.h
@@ -46,8 +46,13 @@ class VSet {
int low = 0;
int high = _data.size() - 1;
- int middle;
const T *a = &_data[0];
+ int middle = 0;
+
+#if DEBUG_ENABLED
+ if (low > high)
+ ERR_PRINT("low > high, this may be a bug");
+#endif
while (low <= high) {
middle = (low + high) / 2;
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 26c0b81428..ad597c8fdc 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -61,7 +61,7 @@
</description>
</method>
<method name="assert">
- <return type="Nil">
+ <return type="void">
</return>
<argument index="0" name="condition" type="bool">
</argument>
@@ -262,7 +262,7 @@
</description>
</method>
<method name="funcref">
- <return type="FuncRef">
+ <return type="Object">
</return>
<argument index="0" name="instance" type="Object">
</argument>
@@ -275,7 +275,7 @@
<method name="hash">
<return type="int">
</return>
- <argument index="0" name="var:Variant" type="Variant">
+ <argument index="0" name="var" type="Variant">
</argument>
<description>
Hash the variable passed and return an integer.
@@ -299,6 +299,18 @@
Get an object by its ID.
</description>
</method>
+ <method name="inverse_lerp">
+ <return type="float">
+ </return>
+ <argument index="0" name="from" type="float">
+ </argument>
+ <argument index="1" name="to" type="float">
+ </argument>
+ <argument index="2" name="value" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="is_inf">
<return type="float">
</return>
@@ -317,6 +329,14 @@
Returns whether s is a NaN (Not-A-Number) value.
</description>
</method>
+ <method name="len">
+ <return type="int">
+ </return>
+ <argument index="0" name="var" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="lerp">
<return type="float">
</return>
@@ -340,7 +360,7 @@
</description>
</method>
<method name="load">
- <return type="Resource">
+ <return type="Object">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -418,64 +438,44 @@
Preload a resource from the filesystem. The resource is loaded during script parsing.
</description>
</method>
- <method name="print">
- <return type="Nil">
+ <method name="print" qualifiers="vararg">
+ <return type="void">
</return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <argument index="1" name="..." type="Variant">
- </argument>
<description>
Print one or more arguments to strings in the best way possible to a console line.
</description>
</method>
<method name="print_stack">
- <return type="Nil">
+ <return type="void">
</return>
<description>
Print a stack track at code location, only works when running with debugger turned on.
</description>
</method>
- <method name="printerr">
- <return type="Nil">
+ <method name="printerr" qualifiers="vararg">
+ <return type="void">
</return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <argument index="1" name="..." type="Variant">
- </argument>
<description>
Print one or more arguments to strings in the best way possible to standard error line.
</description>
</method>
- <method name="printraw">
- <return type="Nil">
+ <method name="printraw" qualifiers="vararg">
+ <return type="void">
</return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <argument index="1" name="..." type="Variant">
- </argument>
<description>
Print one or more arguments to strings in the best way possible to console. No newline is added at the end.
</description>
</method>
- <method name="prints">
- <return type="Nil">
+ <method name="prints" qualifiers="vararg">
+ <return type="void">
</return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <argument index="1" name="..." type="Variant">
- </argument>
<description>
Print one or more arguments to the console with a space between each argument.
</description>
</method>
- <method name="printt">
- <return type="Nil">
+ <method name="printt" qualifiers="vararg">
+ <return type="void">
</return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <argument index="1" name="..." type="Variant">
- </argument>
<description>
Print one or more arguments to the console with a tab between each argument.
</description>
@@ -524,21 +524,35 @@
</description>
</method>
<method name="randomize">
- <return type="Nil">
+ <return type="void">
</return>
<description>
Randomize the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time.
</description>
</method>
- <method name="range">
+ <method name="range" qualifiers="vararg">
<return type="Array">
</return>
- <argument index="0" name="..." type="Variant">
- </argument>
<description>
Return an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial, final-1, increment).
</description>
</method>
+ <method name="range_lerp">
+ <return type="float">
+ </return>
+ <argument index="0" name="value" type="float">
+ </argument>
+ <argument index="1" name="istart" type="float">
+ </argument>
+ <argument index="2" name="istop" type="float">
+ </argument>
+ <argument index="3" name="ostart" type="float">
+ </argument>
+ <argument index="4" name="ostop" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="round">
<return type="float">
</return>
@@ -549,7 +563,7 @@
</description>
</method>
<method name="seed">
- <return type="Nil">
+ <return type="void">
</return>
<argument index="0" name="seed" type="int">
</argument>
@@ -604,13 +618,9 @@
Snap float value to a given step.
</description>
</method>
- <method name="str">
+ <method name="str" qualifiers="vararg">
<return type="String">
</return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <argument index="1" name="..." type="Variant">
- </argument>
<description>
Convert one or more arguments to string in the best way possible.
</description>
@@ -645,7 +655,7 @@
<method name="to_json">
<return type="String">
</return>
- <argument index="0" name="var:Variant" type="Variant">
+ <argument index="0" name="var" type="Variant">
</argument>
<description>
Convert a Variant to json text.
@@ -669,7 +679,7 @@
</description>
</method>
<method name="validate_json">
- <return type="Variant">
+ <return type="String">
</return>
<argument index="0" name="json" type="String">
</argument>
@@ -696,7 +706,7 @@
</description>
</method>
<method name="weakref">
- <return type="WeakRef">
+ <return type="Object">
</return>
<argument index="0" name="obj" type="Object">
</argument>
@@ -719,13 +729,13 @@
</method>
</methods>
<constants>
- <constant name="PI" value="3.141593">
+ <constant name="PI" value="3.141593" enum="">
Constant that represents how many times the diameter of a circumference fits around its perimeter.
</constant>
- <constant name="INF" value="inf">
+ <constant name="INF" value="inf" enum="">
A positive infinity. (For negative infinity, use -INF).
</constant>
- <constant name="NAN" value="nan">
+ <constant name="NAN" value="nan" enum="">
Macro constant that expands to an expression of type float that represents a NaN.
The NaN values are used to identify undefined or non-representable values for floating-point elements, such as the square root of negative numbers or the result of 0/0.
</constant>
@@ -742,6 +752,8 @@
<methods>
</methods>
<members>
+ <member name="ARVRServer" type="ARVRServer" setter="" getter="" brief="">
+ </member>
<member name="AudioServer" type="AudioServer" setter="" getter="" brief="">
[AudioServer] singleton
</member>
@@ -754,9 +766,6 @@
<member name="Geometry" type="Geometry" setter="" getter="" brief="">
[Geometry] singleton
</member>
- <member name="ProjectSettings" type="ProjectSettings" setter="" getter="" brief="">
- [ProjectSettings] singleton
- </member>
<member name="IP" type="IP" setter="" getter="" brief="">
[IP] singleton
</member>
@@ -781,6 +790,9 @@
<member name="PhysicsServer" type="PhysicsServer" setter="" getter="" brief="">
[PhysicsServer] singleton
</member>
+ <member name="ProjectSettings" type="ProjectSettings" setter="" getter="" brief="">
+ [ProjectSettings] singleton
+ </member>
<member name="ResourceLoader" type="ResourceLoader" setter="" getter="" brief="">
[ResourceLoader] singleton
</member>
@@ -831,7 +843,7 @@
<constant name="VALIGN_BOTTOM" value="2">
Vertical bottom alignment, usually for text-derived classes.
</constant>
- <constant name="SPKEY" value="16777216">
+ <constant name="SPKEY" value="16777216" enum="">
Scancodes with this bit applied are non printable.
</constant>
<constant name="KEY_ESCAPE" value="16777217">
@@ -1496,191 +1508,191 @@
</constant>
<constant name="KEY_MASK_GROUP_SWITCH" value="1073741824">
</constant>
- <constant name="BUTTON_LEFT" value="1">
+ <constant name="BUTTON_LEFT" value="1" enum="">
Left Mouse Button
</constant>
- <constant name="BUTTON_RIGHT" value="2">
+ <constant name="BUTTON_RIGHT" value="2" enum="">
Right Mouse Button
</constant>
- <constant name="BUTTON_MIDDLE" value="3">
+ <constant name="BUTTON_MIDDLE" value="3" enum="">
Middle Mouse Button
</constant>
- <constant name="BUTTON_WHEEL_UP" value="4">
+ <constant name="BUTTON_WHEEL_UP" value="4" enum="">
Mouse wheel up
</constant>
- <constant name="BUTTON_WHEEL_DOWN" value="5">
+ <constant name="BUTTON_WHEEL_DOWN" value="5" enum="">
Mouse wheel down
</constant>
- <constant name="BUTTON_WHEEL_LEFT" value="6">
+ <constant name="BUTTON_WHEEL_LEFT" value="6" enum="">
Mouse wheel left button
</constant>
- <constant name="BUTTON_WHEEL_RIGHT" value="7">
+ <constant name="BUTTON_WHEEL_RIGHT" value="7" enum="">
Mouse wheel right button
</constant>
- <constant name="BUTTON_MASK_LEFT" value="1">
+ <constant name="BUTTON_MASK_LEFT" value="1" enum="">
</constant>
- <constant name="BUTTON_MASK_RIGHT" value="2">
+ <constant name="BUTTON_MASK_RIGHT" value="2" enum="">
</constant>
- <constant name="BUTTON_MASK_MIDDLE" value="4">
+ <constant name="BUTTON_MASK_MIDDLE" value="4" enum="">
</constant>
- <constant name="JOY_BUTTON_0" value="0">
+ <constant name="JOY_BUTTON_0" value="0" enum="">
Joypad Button 0
</constant>
- <constant name="JOY_BUTTON_1" value="1">
+ <constant name="JOY_BUTTON_1" value="1" enum="">
Joypad Button 1
</constant>
- <constant name="JOY_BUTTON_2" value="2">
+ <constant name="JOY_BUTTON_2" value="2" enum="">
Joypad Button 2
</constant>
- <constant name="JOY_BUTTON_3" value="3">
+ <constant name="JOY_BUTTON_3" value="3" enum="">
Joypad Button 3
</constant>
- <constant name="JOY_BUTTON_4" value="4">
+ <constant name="JOY_BUTTON_4" value="4" enum="">
Joypad Button 4
</constant>
- <constant name="JOY_BUTTON_5" value="5">
+ <constant name="JOY_BUTTON_5" value="5" enum="">
Joypad Button 5
</constant>
- <constant name="JOY_BUTTON_6" value="6">
+ <constant name="JOY_BUTTON_6" value="6" enum="">
Joypad Button 6
</constant>
- <constant name="JOY_BUTTON_7" value="7">
+ <constant name="JOY_BUTTON_7" value="7" enum="">
Joypad Button 7
</constant>
- <constant name="JOY_BUTTON_8" value="8">
+ <constant name="JOY_BUTTON_8" value="8" enum="">
Joypad Button 8
</constant>
- <constant name="JOY_BUTTON_9" value="9">
+ <constant name="JOY_BUTTON_9" value="9" enum="">
Joypad Button 9
</constant>
- <constant name="JOY_BUTTON_10" value="10">
+ <constant name="JOY_BUTTON_10" value="10" enum="">
Joypad Button 10
</constant>
- <constant name="JOY_BUTTON_11" value="11">
+ <constant name="JOY_BUTTON_11" value="11" enum="">
Joypad Button 11
</constant>
- <constant name="JOY_BUTTON_12" value="12">
+ <constant name="JOY_BUTTON_12" value="12" enum="">
Joypad Button 12
</constant>
- <constant name="JOY_BUTTON_13" value="13">
+ <constant name="JOY_BUTTON_13" value="13" enum="">
Joypad Button 13
</constant>
- <constant name="JOY_BUTTON_14" value="14">
+ <constant name="JOY_BUTTON_14" value="14" enum="">
Joypad Button 14
</constant>
- <constant name="JOY_BUTTON_15" value="15">
+ <constant name="JOY_BUTTON_15" value="15" enum="">
Joypad Button 15
</constant>
- <constant name="JOY_BUTTON_MAX" value="16">
+ <constant name="JOY_BUTTON_MAX" value="16" enum="">
Joypad Button 16
</constant>
- <constant name="JOY_SONY_CIRCLE" value="1">
+ <constant name="JOY_SONY_CIRCLE" value="1" enum="">
DUALSHOCK circle button
</constant>
- <constant name="JOY_SONY_X" value="0">
+ <constant name="JOY_SONY_X" value="0" enum="">
DUALSHOCK X button
</constant>
- <constant name="JOY_SONY_SQUARE" value="2">
+ <constant name="JOY_SONY_SQUARE" value="2" enum="">
DUALSHOCK square button
</constant>
- <constant name="JOY_SONY_TRIANGLE" value="3">
+ <constant name="JOY_SONY_TRIANGLE" value="3" enum="">
DUALSHOCK triangle button
</constant>
- <constant name="JOY_XBOX_B" value="1">
+ <constant name="JOY_XBOX_B" value="1" enum="">
XBOX controller B button
</constant>
- <constant name="JOY_XBOX_A" value="0">
+ <constant name="JOY_XBOX_A" value="0" enum="">
XBOX controller A button
</constant>
- <constant name="JOY_XBOX_X" value="2">
+ <constant name="JOY_XBOX_X" value="2" enum="">
XBOX controller X button
</constant>
- <constant name="JOY_XBOX_Y" value="3">
+ <constant name="JOY_XBOX_Y" value="3" enum="">
XBOX controller Y button
</constant>
- <constant name="JOY_DS_A" value="1">
+ <constant name="JOY_DS_A" value="1" enum="">
</constant>
- <constant name="JOY_DS_B" value="0">
+ <constant name="JOY_DS_B" value="0" enum="">
</constant>
- <constant name="JOY_DS_X" value="3">
+ <constant name="JOY_DS_X" value="3" enum="">
</constant>
- <constant name="JOY_DS_Y" value="2">
+ <constant name="JOY_DS_Y" value="2" enum="">
</constant>
- <constant name="JOY_SELECT" value="10">
+ <constant name="JOY_SELECT" value="10" enum="">
Joypad Button Select
</constant>
- <constant name="JOY_START" value="11">
+ <constant name="JOY_START" value="11" enum="">
Joypad Button Start
</constant>
- <constant name="JOY_DPAD_UP" value="12">
+ <constant name="JOY_DPAD_UP" value="12" enum="">
Joypad DPad Up
</constant>
- <constant name="JOY_DPAD_DOWN" value="13">
+ <constant name="JOY_DPAD_DOWN" value="13" enum="">
Joypad DPad Down
</constant>
- <constant name="JOY_DPAD_LEFT" value="14">
+ <constant name="JOY_DPAD_LEFT" value="14" enum="">
Joypad DPad Left
</constant>
- <constant name="JOY_DPAD_RIGHT" value="15">
+ <constant name="JOY_DPAD_RIGHT" value="15" enum="">
Joypad DPad Right
</constant>
- <constant name="JOY_L" value="4">
+ <constant name="JOY_L" value="4" enum="">
Joypad Left Shoulder Button
</constant>
- <constant name="JOY_L2" value="6">
+ <constant name="JOY_L2" value="6" enum="">
Joypad Left Trigger
</constant>
- <constant name="JOY_L3" value="8">
+ <constant name="JOY_L3" value="8" enum="">
Joypad Left Stick Click
</constant>
- <constant name="JOY_R" value="5">
+ <constant name="JOY_R" value="5" enum="">
Joypad Right Shoulder Button
</constant>
- <constant name="JOY_R2" value="7">
+ <constant name="JOY_R2" value="7" enum="">
Joypad Right Trigger
</constant>
- <constant name="JOY_R3" value="9">
+ <constant name="JOY_R3" value="9" enum="">
Joypad Right Stick Click
</constant>
- <constant name="JOY_AXIS_0" value="0">
+ <constant name="JOY_AXIS_0" value="0" enum="">
Joypad Left Stick Horizontal Axis
</constant>
- <constant name="JOY_AXIS_1" value="1">
+ <constant name="JOY_AXIS_1" value="1" enum="">
Joypad Left Stick Vertical Axis
</constant>
- <constant name="JOY_AXIS_2" value="2">
+ <constant name="JOY_AXIS_2" value="2" enum="">
Joypad Right Stick Horizontal Axis
</constant>
- <constant name="JOY_AXIS_3" value="3">
+ <constant name="JOY_AXIS_3" value="3" enum="">
Joypad Right Stick Vertical Axis
</constant>
- <constant name="JOY_AXIS_4" value="4">
+ <constant name="JOY_AXIS_4" value="4" enum="">
</constant>
- <constant name="JOY_AXIS_5" value="5">
+ <constant name="JOY_AXIS_5" value="5" enum="">
</constant>
- <constant name="JOY_AXIS_6" value="6">
+ <constant name="JOY_AXIS_6" value="6" enum="">
Joypad Left Trigger Analog Axis
</constant>
- <constant name="JOY_AXIS_7" value="7">
+ <constant name="JOY_AXIS_7" value="7" enum="">
Joypad Right Trigger Analog Axis
</constant>
- <constant name="JOY_AXIS_MAX" value="8">
+ <constant name="JOY_AXIS_MAX" value="8" enum="">
</constant>
- <constant name="JOY_ANALOG_LX" value="0">
+ <constant name="JOY_ANALOG_LX" value="0" enum="">
Joypad Left Stick Horizontal Axis
</constant>
- <constant name="JOY_ANALOG_LY" value="1">
+ <constant name="JOY_ANALOG_LY" value="1" enum="">
Joypad Left Stick Vertical Axis
</constant>
- <constant name="JOY_ANALOG_RX" value="2">
+ <constant name="JOY_ANALOG_RX" value="2" enum="">
Joypad Right Stick Horizontal Axis
</constant>
- <constant name="JOY_ANALOG_RY" value="3">
+ <constant name="JOY_ANALOG_RY" value="3" enum="">
Joypad Right Stick Vertical Axis
</constant>
- <constant name="JOY_ANALOG_L2" value="6">
+ <constant name="JOY_ANALOG_L2" value="6" enum="">
</constant>
- <constant name="JOY_ANALOG_R2" value="7">
+ <constant name="JOY_ANALOG_R2" value="7" enum="">
</constant>
<constant name="OK" value="0">
Functions that return Error return OK when everything went ok. Most functions don't return error anyway and/or just print errors to stdout.
@@ -1949,7 +1961,7 @@
</constant>
</constants>
</class>
-<class name="@Native" category="Core">
+<class name="@NativeScript" category="Core">
<brief_description>
</brief_description>
<description>
@@ -1969,6 +1981,542 @@
<constants>
</constants>
</class>
+<class name="ARVRAnchor" inherits="Spatial" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_anchor_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_anchor_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_is_active" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_size" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_anchor_id">
+ <return type="void">
+ </return>
+ <argument index="0" name="anchor_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="anchor_id" type="int" setter="set_anchor_id" getter="get_anchor_id" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
+<class name="ARVRCamera" inherits="Camera" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
+<class name="ARVRController" inherits="Spatial" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_controller_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_controller_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_is_active" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_joystick_axis" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="axis" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_joystick_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_button_pressed" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="button" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_controller_id">
+ <return type="void">
+ </return>
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="controller_id" type="int" setter="set_controller_id" getter="get_controller_id" brief="">
+ </member>
+ </members>
+ <signals>
+ <signal name="button_pressed">
+ <argument index="0" name="button" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ <signal name="button_release">
+ <argument index="0" name="button" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
+<class name="ARVRInterface" inherits="Reference" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_recommended_render_targetsize">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="hmd_is_present">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="initialize">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_initialized">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_installed">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_primary">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_is_primary">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="supports_hmd">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="uninitialize">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="primary" type="bool" setter="set_is_primary" getter="is_primary" brief="">
+ </member>
+ </members>
+ <constants>
+ <constant name="EYE_MONO" value="0">
+ </constant>
+ <constant name="EYE_LEFT" value="1">
+ </constant>
+ <constant name="EYE_RIGHT" value="2">
+ </constant>
+ </constants>
+</class>
+<class name="ARVROrigin" inherits="Spatial" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_world_scale" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_world_scale">
+ <return type="void">
+ </return>
+ <argument index="0" name="world_scale" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
+<class name="ARVRPositionalTracker" inherits="Object" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_joy_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_orientation" qualifiers="const">
+ <return type="Basis">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_position" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_tracks_orientation" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_tracks_position" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_transform" qualifiers="const">
+ <return type="Transform">
+ </return>
+ <argument index="0" name="adjust_by_reference_frame" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_type" qualifiers="const">
+ <return type="int" enum="ARVRServer.TrackerType">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
+<class name="ARVRScriptInterface" inherits="ARVRInterface" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="_get_projection_for_eye" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="commit_for_eye" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <argument index="0" name="eye" type="int">
+ </argument>
+ <argument index="1" name="render_target" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_recommended_render_targetsize" qualifiers="virtual">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_transform_for_eye" qualifiers="virtual">
+ <return type="Transform">
+ </return>
+ <argument index="0" name="eye" type="int">
+ </argument>
+ <argument index="1" name="cam_transform" type="Transform">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="hmd_is_present" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="initialize" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_initialized" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_installed" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_stereo" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="process" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="supports_hmd" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="uninitialize" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
+<class name="ARVRServer" inherits="Object" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="add_interface">
+ <return type="void">
+ </return>
+ <argument index="0" name="arg0" type="ARVRInterface">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="find_interface" qualifiers="const">
+ <return type="ARVRInterface">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_interface" qualifiers="const">
+ <return type="ARVRInterface">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_interface_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_reference_frame" qualifiers="const">
+ <return type="Transform">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_tracker" qualifiers="const">
+ <return type="ARVRPositionalTracker">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_tracker_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_world_scale" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="remove_interface">
+ <return type="void">
+ </return>
+ <argument index="0" name="arg0" type="ARVRInterface">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="request_reference_frame">
+ <return type="void">
+ </return>
+ <argument index="0" name="ignore_tilt" type="bool">
+ </argument>
+ <argument index="1" name="keep_height" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_primary_interface">
+ <return type="void">
+ </return>
+ <argument index="0" name="arg0" type="ARVRInterface">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_world_scale">
+ <return type="void">
+ </return>
+ <argument index="0" name="arg0" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" brief="">
+ </member>
+ </members>
+ <signals>
+ <signal name="interface_added">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ <signal name="interface_removed">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ <signal name="tracker_added">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="type" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ <signal name="tracker_removed">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ <constant name="TRACKER_CONTROLLER" value="1">
+ </constant>
+ <constant name="TRACKER_BASESTATION" value="2">
+ </constant>
+ <constant name="TRACKER_ANCHOR" value="4">
+ </constant>
+ <constant name="TRACKER_UNKNOWN" value="128">
+ </constant>
+ <constant name="TRACKER_ANY_KNOWN" value="127">
+ </constant>
+ <constant name="TRACKER_ANY" value="255">
+ </constant>
+ </constants>
+</class>
<class name="AStar" inherits="Reference" category="Core">
<brief_description>
AStar class representation that uses vectors as edges.
@@ -1979,6 +2527,8 @@
</description>
<methods>
<method name="_compute_cost" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="from_id" type="int">
</argument>
<argument index="1" name="to_id" type="int">
@@ -1987,6 +2537,8 @@
</description>
</method>
<method name="_estimate_cost" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="from_id" type="int">
</argument>
<argument index="1" name="to_id" type="int">
@@ -1995,11 +2547,13 @@
</description>
</method>
<method name="add_point">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="pos" type="Vector3">
</argument>
- <argument index="2" name="weight_scale" type="float" default="1">
+ <argument index="2" name="weight_scale" type="float" default="1.0">
</argument>
<description>
Add a new point at the given position [code]pos[/code] with the given identifier [code]id[/code]. The [code]weight_scale[/code] has to be 1 or larger.
@@ -2017,11 +2571,15 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear all the points and segments from AStar instance.
</description>
</method>
<method name="connect_points">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="to_id" type="int">
@@ -2033,6 +2591,8 @@
</description>
</method>
<method name="disconnect_points">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="to_id" type="int">
@@ -2115,6 +2675,8 @@
</description>
</method>
<method name="remove_point">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
@@ -2164,14 +2726,14 @@
</description>
</method>
<method name="get_label">
- <return type="Object">
+ <return type="Label">
</return>
<description>
Return the label used for built-in text.
</description>
</method>
<method name="get_ok">
- <return type="Object">
+ <return type="Button">
</return>
<description>
Return the OK Button.
@@ -2185,15 +2747,17 @@
</description>
</method>
<method name="register_text_enter">
- <return type="LineEdit">
+ <return type="void">
</return>
- <argument index="0" name="line_edit" type="Object">
+ <argument index="0" name="line_edit" type="Node">
</argument>
<description>
Register a [LineEdit] in the dialog. When the enter key is pressed, the dialog will be accepted.
</description>
</method>
<method name="set_hide_on_ok">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -2201,6 +2765,8 @@
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -2296,6 +2862,8 @@
</description>
</method>
<method name="play">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String" default="&quot;&quot;">
</argument>
<description>
@@ -2303,6 +2871,8 @@
</description>
</method>
<method name="set_animation">
+ <return type="void">
+ </return>
<argument index="0" name="animation" type="String">
</argument>
<description>
@@ -2310,6 +2880,8 @@
</description>
</method>
<method name="set_centered">
+ <return type="void">
+ </return>
<argument index="0" name="centered" type="bool">
</argument>
<description>
@@ -2317,6 +2889,8 @@
</description>
</method>
<method name="set_flip_h">
+ <return type="void">
+ </return>
<argument index="0" name="flip_h" type="bool">
</argument>
<description>
@@ -2324,6 +2898,8 @@
</description>
</method>
<method name="set_flip_v">
+ <return type="void">
+ </return>
<argument index="0" name="flip_v" type="bool">
</argument>
<description>
@@ -2331,6 +2907,8 @@
</description>
</method>
<method name="set_frame">
+ <return type="void">
+ </return>
<argument index="0" name="frame" type="int">
</argument>
<description>
@@ -2338,6 +2916,8 @@
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -2345,6 +2925,8 @@
</description>
</method>
<method name="set_sprite_frames">
+ <return type="void">
+ </return>
<argument index="0" name="sprite_frames" type="SpriteFrames">
</argument>
<description>
@@ -2352,6 +2934,8 @@
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
Stop the current animation (does not reset the frame counter).
</description>
@@ -2425,6 +3009,8 @@
</description>
</method>
<method name="play">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String" default="&quot;&quot;">
</argument>
<description>
@@ -2432,6 +3018,8 @@
</description>
</method>
<method name="set_animation">
+ <return type="void">
+ </return>
<argument index="0" name="animation" type="String">
</argument>
<description>
@@ -2439,6 +3027,8 @@
</description>
</method>
<method name="set_frame">
+ <return type="void">
+ </return>
<argument index="0" name="frame" type="int">
</argument>
<description>
@@ -2446,6 +3036,8 @@
</description>
</method>
<method name="set_sprite_frames">
+ <return type="void">
+ </return>
<argument index="0" name="sprite_frames" type="SpriteFrames">
</argument>
<description>
@@ -2453,6 +3045,8 @@
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
Stop the current animation (does not reset the frame counter).
</description>
@@ -2490,7 +3084,7 @@
<method name="add_track">
<return type="int">
</return>
- <argument index="0" name="type" type="int">
+ <argument index="0" name="type" type="int" enum="Animation.TrackType">
</argument>
<argument index="1" name="at_pos" type="int" default="-1">
</argument>
@@ -2499,6 +3093,8 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear the animation (clear all tracks and reset all).
</description>
@@ -2576,6 +3172,8 @@
</description>
</method>
<method name="remove_track">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -2583,6 +3181,8 @@
</description>
</method>
<method name="set_length">
+ <return type="void">
+ </return>
<argument index="0" name="time_sec" type="float">
</argument>
<description>
@@ -2590,6 +3190,8 @@
</description>
</method>
<method name="set_loop">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -2597,6 +3199,8 @@
</description>
</method>
<method name="set_step">
+ <return type="void">
+ </return>
<argument index="0" name="size_sec" type="float">
</argument>
<description>
@@ -2625,7 +3229,7 @@
</description>
</method>
<method name="track_get_interpolation_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Animation.InterpolationType">
</return>
<argument index="0" name="idx" type="int">
</argument>
@@ -2665,6 +3269,8 @@
</description>
</method>
<method name="track_get_key_value" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
@@ -2683,7 +3289,7 @@
</description>
</method>
<method name="track_get_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Animation.TrackType">
</return>
<argument index="0" name="idx" type="int">
</argument>
@@ -2692,6 +3298,8 @@
</description>
</method>
<method name="track_insert_key">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="time" type="float">
@@ -2714,6 +3322,8 @@
</description>
</method>
<method name="track_move_down">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -2721,6 +3331,8 @@
</description>
</method>
<method name="track_move_up">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -2728,6 +3340,8 @@
</description>
</method>
<method name="track_remove_key">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
@@ -2737,6 +3351,8 @@
</description>
</method>
<method name="track_remove_key_at_pos">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="pos" type="float">
@@ -2746,6 +3362,8 @@
</description>
</method>
<method name="track_set_imported">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="imported" type="bool">
@@ -2755,6 +3373,8 @@
</description>
</method>
<method name="track_set_interpolation_loop_wrap">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="interpolation" type="bool">
@@ -2763,15 +3383,19 @@
</description>
</method>
<method name="track_set_interpolation_type">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="interpolation" type="int">
+ <argument index="1" name="interpolation" type="int" enum="Animation.InterpolationType">
</argument>
<description>
Set the interpolation type of a given track, from the INTERPOLATION_* enum.
</description>
</method>
<method name="track_set_key_transition">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
@@ -2783,6 +3407,8 @@
</description>
</method>
<method name="track_set_key_value">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="key" type="int">
@@ -2794,6 +3420,8 @@
</description>
</method>
<method name="track_set_path">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="path" type="NodePath">
@@ -2844,7 +3472,7 @@
</description>
</method>
<method name="value_track_get_update_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Animation.UpdateMode">
</return>
<argument index="0" name="idx" type="int">
</argument>
@@ -2852,9 +3480,11 @@
</description>
</method>
<method name="value_track_set_update_mode">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Animation.UpdateMode">
</argument>
<description>
</description>
@@ -2896,7 +3526,7 @@
</description>
<methods>
<method name="add_animation">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="name" type="String">
</argument>
@@ -2907,6 +3537,8 @@
</description>
</method>
<method name="advance">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<description>
@@ -2922,6 +3554,8 @@
</description>
</method>
<method name="animation_set_next">
+ <return type="void">
+ </return>
<argument index="0" name="anim_from" type="String">
</argument>
<argument index="1" name="anim_to" type="String">
@@ -2930,11 +3564,15 @@
</description>
</method>
<method name="clear_caches">
+ <return type="void">
+ </return>
<description>
The animation player creates caches for faster access to the nodes it will animate. However, if a specific node is removed, it may not notice it, so clear_caches will force the player to search for the nodes again.
</description>
</method>
<method name="clear_queue">
+ <return type="void">
+ </return>
<description>
If animations are queued to play, clear them.
</description>
@@ -2965,7 +3603,7 @@
</description>
</method>
<method name="get_animation_process_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AnimationPlayer.AnimationProcessMode">
</return>
<description>
Return the mode in which the animation player processes. See [method set_animation_process_mode].
@@ -3062,11 +3700,13 @@
</description>
</method>
<method name="play">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String" default="&quot;&quot;">
</argument>
<argument index="1" name="custom_blend" type="float" default="-1">
</argument>
- <argument index="2" name="custom_speed" type="float" default="1">
+ <argument index="2" name="custom_speed" type="float" default="1.0">
</argument>
<argument index="3" name="from_end" type="bool" default="false">
</argument>
@@ -3075,6 +3715,8 @@
</description>
</method>
<method name="play_backwards">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String" default="&quot;&quot;">
</argument>
<argument index="1" name="custom_blend" type="float" default="-1">
@@ -3084,6 +3726,8 @@
</description>
</method>
<method name="queue">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -3091,6 +3735,8 @@
</description>
</method>
<method name="remove_animation">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -3098,6 +3744,8 @@
</description>
</method>
<method name="rename_animation">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="newname" type="String">
@@ -3107,6 +3755,8 @@
</description>
</method>
<method name="seek">
+ <return type="void">
+ </return>
<argument index="0" name="pos_sec" type="float">
</argument>
<argument index="1" name="update" type="bool" default="false">
@@ -3116,6 +3766,8 @@
</description>
</method>
<method name="set_active">
+ <return type="void">
+ </return>
<argument index="0" name="active" type="bool">
</argument>
<description>
@@ -3123,13 +3775,17 @@
</description>
</method>
<method name="set_animation_process_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="AnimationPlayer.AnimationProcessMode">
</argument>
<description>
Set the mode in which the animation player processes. By default, it processes on idle time (framerate dependent), but using fixed time works well for animating static collision bodies in 2D and 3D. See enum ANIMATION_PROCESS_*.
</description>
</method>
<method name="set_autoplay">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -3137,6 +3793,8 @@
</description>
</method>
<method name="set_blend_time">
+ <return type="void">
+ </return>
<argument index="0" name="anim_from" type="String">
</argument>
<argument index="1" name="anim_to" type="String">
@@ -3148,6 +3806,8 @@
</description>
</method>
<method name="set_current_animation">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<description>
@@ -3155,6 +3815,8 @@
</description>
</method>
<method name="set_default_blend_time">
+ <return type="void">
+ </return>
<argument index="0" name="sec" type="float">
</argument>
<description>
@@ -3162,6 +3824,8 @@
</description>
</method>
<method name="set_root">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="NodePath">
</argument>
<description>
@@ -3169,6 +3833,8 @@
</description>
</method>
<method name="set_speed_scale">
+ <return type="void">
+ </return>
<argument index="0" name="speed" type="float">
</argument>
<description>
@@ -3176,6 +3842,8 @@
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<argument index="0" name="reset" type="bool" default="true">
</argument>
<description>
@@ -3183,6 +3851,8 @@
</description>
</method>
<method name="stop_all">
+ <return type="void">
+ </return>
<description>
Stop playback of animations (deprecated).
</description>
@@ -3191,7 +3861,7 @@
<members>
<member name="playback_default_blend_time" type="float" setter="set_default_blend_time" getter="get_default_blend_time" brief="">
</member>
- <member name="playback_process_mode" type="int" setter="set_animation_process_mode" getter="get_animation_process_mode" brief="">
+ <member name="playback_process_mode" type="int" setter="set_animation_process_mode" getter="get_animation_process_mode" brief="" enum="AnimationPlayer.AnimationProcessMode">
</member>
<member name="root_node" type="NodePath" setter="set_root" getter="get_root" brief="">
</member>
@@ -3239,7 +3909,9 @@
</description>
<methods>
<method name="add_node">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="AnimationTreePlayer.NodeType">
</argument>
<argument index="1" name="id" type="String">
</argument>
@@ -3248,6 +3920,8 @@
</description>
</method>
<method name="advance">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<description>
@@ -3270,6 +3944,8 @@
</description>
</method>
<method name="animation_node_set_animation">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="animation" type="Animation">
@@ -3279,6 +3955,8 @@
</description>
</method>
<method name="animation_node_set_filter_path">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="path" type="NodePath">
@@ -3289,6 +3967,8 @@
</description>
</method>
<method name="animation_node_set_master_animation">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="source" type="String">
@@ -3317,6 +3997,8 @@
</description>
</method>
<method name="blend2_node_set_amount">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="blend" type="float">
@@ -3325,6 +4007,8 @@
</description>
</method>
<method name="blend2_node_set_filter_path">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="path" type="NodePath">
@@ -3343,6 +4027,8 @@
</description>
</method>
<method name="blend3_node_set_amount">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="blend" type="float">
@@ -3359,6 +4045,8 @@
</description>
</method>
<method name="blend4_node_set_amount">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="blend" type="Vector2">
@@ -3367,7 +4055,7 @@
</description>
</method>
<method name="connect_nodes">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="id" type="String">
</argument>
@@ -3379,6 +4067,8 @@
</description>
</method>
<method name="disconnect_nodes">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="dst_input_idx" type="int">
@@ -3387,7 +4077,7 @@
</description>
</method>
<method name="get_animation_process_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AnimationTreePlayer.AnimationProcessMode">
</return>
<description>
</description>
@@ -3425,6 +4115,8 @@
</description>
</method>
<method name="mix_node_set_amount">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="ratio" type="float">
@@ -3470,7 +4162,7 @@
</description>
</method>
<method name="node_get_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AnimationTreePlayer.NodeType">
</return>
<argument index="0" name="id" type="String">
</argument>
@@ -3479,7 +4171,7 @@
</description>
</method>
<method name="node_rename">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="node" type="String">
</argument>
@@ -3490,6 +4182,8 @@
</description>
</method>
<method name="node_set_pos">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="screen_pos" type="Vector2">
@@ -3546,6 +4240,8 @@
</description>
</method>
<method name="oneshot_node_set_autorestart">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="enable" type="bool">
@@ -3554,6 +4250,8 @@
</description>
</method>
<method name="oneshot_node_set_autorestart_delay">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="delay_sec" type="float">
@@ -3562,6 +4260,8 @@
</description>
</method>
<method name="oneshot_node_set_autorestart_random_delay">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="rand_sec" type="float">
@@ -3570,6 +4270,8 @@
</description>
</method>
<method name="oneshot_node_set_fadein_time">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="time_sec" type="float">
@@ -3578,6 +4280,8 @@
</description>
</method>
<method name="oneshot_node_set_fadeout_time">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="time_sec" type="float">
@@ -3586,6 +4290,8 @@
</description>
</method>
<method name="oneshot_node_set_filter_path">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="path" type="NodePath">
@@ -3596,50 +4302,68 @@
</description>
</method>
<method name="oneshot_node_start">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<description>
</description>
</method>
<method name="oneshot_node_stop">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<description>
</description>
</method>
<method name="recompute_caches">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="remove_node">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<description>
</description>
</method>
<method name="reset">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set_active">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_animation_process_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="AnimationTreePlayer.AnimationProcessMode">
</argument>
<description>
</description>
</method>
<method name="set_base_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_master_player">
+ <return type="void">
+ </return>
<argument index="0" name="nodepath" type="NodePath">
</argument>
<description>
@@ -3654,6 +4378,8 @@
</description>
</method>
<method name="timescale_node_set_scale">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="scale" type="float">
@@ -3662,6 +4388,8 @@
</description>
</method>
<method name="timeseek_node_seek">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="pos_sec" type="float">
@@ -3670,6 +4398,8 @@
</description>
</method>
<method name="transition_node_delete_input">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="input_idx" type="int">
@@ -3712,6 +4442,8 @@
</description>
</method>
<method name="transition_node_set_current">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="input_idx" type="int">
@@ -3720,6 +4452,8 @@
</description>
</method>
<method name="transition_node_set_input_auto_advance">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="input_idx" type="int">
@@ -3730,6 +4464,8 @@
</description>
</method>
<method name="transition_node_set_input_count">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="count" type="int">
@@ -3738,6 +4474,8 @@
</description>
</method>
<method name="transition_node_set_xfade_time">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="String">
</argument>
<argument index="1" name="time_sec" type="float">
@@ -3747,7 +4485,7 @@
</method>
</methods>
<members>
- <member name="playback_process_mode" type="int" setter="set_animation_process_mode" getter="get_animation_process_mode" brief="">
+ <member name="playback_process_mode" type="int" setter="set_animation_process_mode" getter="get_animation_process_mode" brief="" enum="AnimationTreePlayer.AnimationProcessMode">
</member>
</members>
<constants>
@@ -3894,7 +4632,7 @@
</description>
</method>
<method name="get_space_override_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Area.SpaceOverride">
</return>
<description>
Return the space override mode.
@@ -3936,7 +4674,7 @@
<method name="overlaps_area" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="area" type="Object">
+ <argument index="0" name="area" type="Node">
</argument>
<description>
Return whether the area passed is totally or partially inside this area.
@@ -3945,13 +4683,15 @@
<method name="overlaps_body" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="body" type="Object">
+ <argument index="0" name="body" type="Node">
</argument>
<description>
Return whether the body passed is totally or partially inside this area.
</description>
</method>
<method name="set_angular_damp">
+ <return type="void">
+ </return>
<argument index="0" name="angular_damp" type="float">
</argument>
<description>
@@ -3960,18 +4700,24 @@
</description>
</method>
<method name="set_audio_bus">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="set_audio_bus_override">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="collision_layer" type="int">
</argument>
<description>
@@ -3981,6 +4727,8 @@
</description>
</method>
<method name="set_collision_layer_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -3990,6 +4738,8 @@
</description>
</method>
<method name="set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="collision_mask" type="int">
</argument>
<description>
@@ -3997,6 +4747,8 @@
</description>
</method>
<method name="set_collision_mask_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -4006,6 +4758,8 @@
</description>
</method>
<method name="set_gravity">
+ <return type="void">
+ </return>
<argument index="0" name="gravity" type="float">
</argument>
<description>
@@ -4014,6 +4768,8 @@
</description>
</method>
<method name="set_gravity_distance_scale">
+ <return type="void">
+ </return>
<argument index="0" name="distance_scale" type="float">
</argument>
<description>
@@ -4021,6 +4777,8 @@
</description>
</method>
<method name="set_gravity_is_point">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -4028,6 +4786,8 @@
</description>
</method>
<method name="set_gravity_vector">
+ <return type="void">
+ </return>
<argument index="0" name="vector" type="Vector3">
</argument>
<description>
@@ -4036,6 +4796,8 @@
</description>
</method>
<method name="set_linear_damp">
+ <return type="void">
+ </return>
<argument index="0" name="linear_damp" type="float">
</argument>
<description>
@@ -4044,6 +4806,8 @@
</description>
</method>
<method name="set_monitorable">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -4051,6 +4815,8 @@
</description>
</method>
<method name="set_monitoring">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -4058,33 +4824,43 @@
</description>
</method>
<method name="set_priority">
+ <return type="void">
+ </return>
<argument index="0" name="priority" type="float">
</argument>
<description>
- Set the order in which the area is processed. Greater values mean the area gets processed first. This is useful for areas which have an space override different from AREA_SPACE_OVERRIDE_DISABLED or AREA_SPACE_OVERRIDE_COMBINE, as they replace values, and are thus order-dependent.
+ Set the order in which the area is processed. Greater values mean the area gets processed first. This is useful for areas which have a space override different from AREA_SPACE_OVERRIDE_DISABLED or AREA_SPACE_OVERRIDE_COMBINE, as they replace values, and are thus order-dependent.
Areas with the same priority value get evaluated in an unpredictable order, and should be differentiated if evaluation order is to be important.
</description>
</method>
<method name="set_reverb_amount">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_reverb_bus">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="set_reverb_uniformity">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_space_override_mode">
- <argument index="0" name="enable" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="int" enum="Area.SpaceOverride">
</argument>
<description>
Set the space override mode. This mode controls how an area affects gravity and damp.
@@ -4096,6 +4872,8 @@
</description>
</method>
<method name="set_use_reverb_bus">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -4127,7 +4905,7 @@
</member>
<member name="monitoring" type="bool" setter="set_monitoring" getter="is_monitoring" brief="">
</member>
- <member name="priority" type="int" setter="set_priority" getter="get_priority" brief="">
+ <member name="priority" type="float" setter="set_priority" getter="get_priority" brief="">
</member>
<member name="reverb_bus_amount" type="float" setter="set_reverb_amount" getter="get_reverb_amount" brief="">
</member>
@@ -4137,7 +4915,7 @@
</member>
<member name="reverb_bus_uniformity" type="float" setter="set_reverb_uniformity" getter="get_reverb_uniformity" brief="">
</member>
- <member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" brief="">
+ <member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" brief="" enum="Area.SpaceOverride">
</member>
</members>
<signals>
@@ -4328,7 +5106,7 @@
</description>
</method>
<method name="get_space_override_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Area2D.SpaceOverride">
</return>
<description>
Return the space override mode.
@@ -4364,7 +5142,7 @@
<method name="overlaps_area" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="area" type="Object">
+ <argument index="0" name="area" type="Node">
</argument>
<description>
Return whether the area passed is totally or partially inside this area.
@@ -4373,13 +5151,15 @@
<method name="overlaps_body" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="body" type="Object">
+ <argument index="0" name="body" type="Node">
</argument>
<description>
Return whether the body passed is totally or partially inside this area.
</description>
</method>
<method name="set_angular_damp">
+ <return type="void">
+ </return>
<argument index="0" name="angular_damp" type="float">
</argument>
<description>
@@ -4388,18 +5168,24 @@
</description>
</method>
<method name="set_audio_bus">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="set_audio_bus_override">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="collision_layer" type="int">
</argument>
<description>
@@ -4409,6 +5195,8 @@
</description>
</method>
<method name="set_collision_layer_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -4418,6 +5206,8 @@
</description>
</method>
<method name="set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="collision_mask" type="int">
</argument>
<description>
@@ -4425,6 +5215,8 @@
</description>
</method>
<method name="set_collision_mask_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -4434,6 +5226,8 @@
</description>
</method>
<method name="set_gravity">
+ <return type="void">
+ </return>
<argument index="0" name="gravity" type="float">
</argument>
<description>
@@ -4442,6 +5236,8 @@
</description>
</method>
<method name="set_gravity_distance_scale">
+ <return type="void">
+ </return>
<argument index="0" name="distance_scale" type="float">
</argument>
<description>
@@ -4449,6 +5245,8 @@
</description>
</method>
<method name="set_gravity_is_point">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -4456,6 +5254,8 @@
</description>
</method>
<method name="set_gravity_vector">
+ <return type="void">
+ </return>
<argument index="0" name="vector" type="Vector2">
</argument>
<description>
@@ -4464,6 +5264,8 @@
</description>
</method>
<method name="set_linear_damp">
+ <return type="void">
+ </return>
<argument index="0" name="linear_damp" type="float">
</argument>
<description>
@@ -4472,6 +5274,8 @@
</description>
</method>
<method name="set_monitorable">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -4479,6 +5283,8 @@
</description>
</method>
<method name="set_monitoring">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -4486,15 +5292,19 @@
</description>
</method>
<method name="set_priority">
+ <return type="void">
+ </return>
<argument index="0" name="priority" type="float">
</argument>
<description>
- Set the order in which the area is processed. Greater values mean the area gets processed first. This is useful for areas which have an space override different from AREA_SPACE_OVERRIDE_DISABLED or AREA_SPACE_OVERRIDE_COMBINE, as they replace values, and are thus order-dependent.
+ Set the order in which the area is processed. Greater values mean the area gets processed first. This is useful for areas which have a space override different from AREA_SPACE_OVERRIDE_DISABLED or AREA_SPACE_OVERRIDE_COMBINE, as they replace values, and are thus order-dependent.
Areas with the same priority value get evaluated in an unpredictable order, and should be differentiated if evaluation order is to be important.
</description>
</method>
<method name="set_space_override_mode">
- <argument index="0" name="enable" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="int" enum="Area2D.SpaceOverride">
</argument>
<description>
Set the space override mode. This mode controls how an area affects gravity and damp.
@@ -4531,9 +5341,9 @@
</member>
<member name="monitoring" type="bool" setter="set_monitoring" getter="is_monitoring" brief="">
</member>
- <member name="priority" type="int" setter="set_priority" getter="get_priority" brief="">
+ <member name="priority" type="float" setter="set_priority" getter="get_priority" brief="">
</member>
- <member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" brief="">
+ <member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" brief="" enum="Area2D.SpaceOverride">
</member>
</members>
<signals>
@@ -4860,7 +5670,7 @@
<argument index="1" name="func" type="String">
</argument>
<description>
- Sort the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return true if the first argument is less than the second, and return false otherwise.
+ Sort the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return true if the first argument is less than the second, and return false otherwise. Note: you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior.
</description>
</method>
</methods>
@@ -4874,17 +5684,21 @@
</description>
<methods>
<method name="add_blend_shape">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="add_surface_from_arrays">
- <argument index="0" name="primitive" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="primitive" type="int" enum="Mesh.PrimitiveType">
</argument>
<argument index="1" name="arrays" type="Array">
</argument>
- <argument index="2" name="blend_shapes" type="Array" default="[]">
+ <argument index="2" name="blend_shapes" type="Array" default="[ ]">
</argument>
<argument index="3" name="compress_flags" type="int" default="97792">
</argument>
@@ -4894,10 +5708,14 @@
</description>
</method>
<method name="center_geometry">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="clear_blend_shapes">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -4908,7 +5726,7 @@
</description>
</method>
<method name="get_blend_shape_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Mesh.BlendShapeMode">
</return>
<description>
</description>
@@ -4935,16 +5753,22 @@
</description>
</method>
<method name="regen_normalmaps">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set_blend_shape_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Mesh.BlendShapeMode">
</argument>
<description>
</description>
</method>
<method name="set_custom_aabb">
+ <return type="void">
+ </return>
<argument index="0" name="aabb" type="Rect3">
</argument>
<description>
@@ -4995,7 +5819,7 @@
</description>
</method>
<method name="surface_get_primitive_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Mesh.PrimitiveType">
</return>
<argument index="0" name="surf_idx" type="int">
</argument>
@@ -5004,6 +5828,8 @@
</description>
</method>
<method name="surface_remove">
+ <return type="void">
+ </return>
<argument index="0" name="surf_idx" type="int">
</argument>
<description>
@@ -5011,6 +5837,8 @@
</description>
</method>
<method name="surface_set_material">
+ <return type="void">
+ </return>
<argument index="0" name="surf_idx" type="int">
</argument>
<argument index="1" name="material" type="Material">
@@ -5019,6 +5847,8 @@
</description>
</method>
<method name="surface_set_name">
+ <return type="void">
+ </return>
<argument index="0" name="surf_idx" type="int">
</argument>
<argument index="1" name="name" type="String">
@@ -5029,10 +5859,10 @@
</method>
</methods>
<constants>
- <constant name="NO_INDEX_ARRAY" value="-1">
+ <constant name="NO_INDEX_ARRAY" value="-1" enum="">
Default value used for index_array_len when no indices are present.
</constant>
- <constant name="ARRAY_WEIGHTS_SIZE" value="4">
+ <constant name="ARRAY_WEIGHTS_SIZE" value="4" enum="">
Amount of weights/bone indices per vertex (always 4).
</constant>
<constant name="ARRAY_VERTEX" value="0">
@@ -5062,6 +5892,8 @@
<constant name="ARRAY_INDEX" value="8">
Array of integers, used as indices referencing vertices. No index can be beyond the vertex array size.
</constant>
+ <constant name="ARRAY_MAX" value="9">
+ </constant>
<constant name="ARRAY_FORMAT_VERTEX" value="1">
Array format will include vertices (mandatory).
</constant>
@@ -5116,18 +5948,24 @@
</description>
</method>
<method name="set_atlas">
+ <return type="void">
+ </return>
<argument index="0" name="atlas" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_margin">
+ <return type="void">
+ </return>
<argument index="0" name="margin" type="Rect2">
</argument>
<description>
</description>
</method>
<method name="set_region">
+ <return type="void">
+ </return>
<argument index="0" name="region" type="Rect2">
</argument>
<description>
@@ -5142,12 +5980,6 @@
<member name="region" type="Rect2" setter="set_region" getter="get_region" brief="">
</member>
</members>
- <signals>
- <signal name="atlas_changed">
- <description>
- </description>
- </signal>
- </signals>
<constants>
</constants>
</class>
@@ -5184,6 +6016,8 @@
</description>
</method>
<method name="set_volume_db">
+ <return type="void">
+ </return>
<argument index="0" name="volume" type="float">
</argument>
<description>
@@ -5290,18 +6124,24 @@
</description>
</method>
<method name="set_dry">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_voice_count">
+ <return type="void">
+ </return>
<argument index="0" name="voices" type="int">
</argument>
<description>
</description>
</method>
<method name="set_voice_cutoff_hz">
+ <return type="void">
+ </return>
<argument index="0" name="voice_idx" type="int">
</argument>
<argument index="1" name="cutoff_hz" type="float">
@@ -5310,6 +6150,8 @@
</description>
</method>
<method name="set_voice_delay_ms">
+ <return type="void">
+ </return>
<argument index="0" name="voice_idx" type="int">
</argument>
<argument index="1" name="delay_ms" type="float">
@@ -5318,6 +6160,8 @@
</description>
</method>
<method name="set_voice_depth_ms">
+ <return type="void">
+ </return>
<argument index="0" name="voice_idx" type="int">
</argument>
<argument index="1" name="depth_ms" type="float">
@@ -5326,6 +6170,8 @@
</description>
</method>
<method name="set_voice_level_db">
+ <return type="void">
+ </return>
<argument index="0" name="voice_idx" type="int">
</argument>
<argument index="1" name="level_db" type="float">
@@ -5334,6 +6180,8 @@
</description>
</method>
<method name="set_voice_pan">
+ <return type="void">
+ </return>
<argument index="0" name="voice_idx" type="int">
</argument>
<argument index="1" name="pan" type="float">
@@ -5342,6 +6190,8 @@
</description>
</method>
<method name="set_voice_rate_hz">
+ <return type="void">
+ </return>
<argument index="0" name="voice_idx" type="int">
</argument>
<argument index="1" name="rate_hz" type="float">
@@ -5350,6 +6200,8 @@
</description>
</method>
<method name="set_wet">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
@@ -5464,42 +6316,56 @@
</description>
</method>
<method name="set_attack_us">
+ <return type="void">
+ </return>
<argument index="0" name="attack_us" type="float">
</argument>
<description>
</description>
</method>
<method name="set_gain">
+ <return type="void">
+ </return>
<argument index="0" name="gain" type="float">
</argument>
<description>
</description>
</method>
<method name="set_mix">
+ <return type="void">
+ </return>
<argument index="0" name="mix" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="ratio" type="float">
</argument>
<description>
</description>
</method>
<method name="set_release_ms">
+ <return type="void">
+ </return>
<argument index="0" name="release_ms" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sidechain">
+ <return type="void">
+ </return>
<argument index="0" name="sidechain" type="String">
</argument>
<description>
</description>
</method>
<method name="set_threshold">
+ <return type="void">
+ </return>
<argument index="0" name="threshold" type="float">
</argument>
<description>
@@ -5517,7 +6383,7 @@
</member>
<member name="release_ms" type="float" setter="set_release_ms" getter="get_release_ms" brief="">
</member>
- <member name="sidechain" type="float" setter="set_sidechain" getter="get_sidechain" brief="">
+ <member name="sidechain" type="String" setter="set_sidechain" getter="get_sidechain" brief="">
</member>
<member name="threshold" type="float" setter="set_threshold" getter="get_threshold" brief="">
</member>
@@ -5610,78 +6476,104 @@
</description>
</method>
<method name="set_dry">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_feedback_active">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_feedback_delay_ms">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_feedback_level_db">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_feedback_lowpass">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tap1_active">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_tap1_delay_ms">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tap1_level_db">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tap1_pan">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tap2_active">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_tap2_delay_ms">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tap2_level_db">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tap2_pan">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
@@ -5738,7 +6630,7 @@
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioEffectDistortion.Mode">
</return>
<description>
</description>
@@ -5756,30 +6648,40 @@
</description>
</method>
<method name="set_drive">
+ <return type="void">
+ </return>
<argument index="0" name="drive" type="float">
</argument>
<description>
</description>
</method>
<method name="set_keep_hf_hz">
+ <return type="void">
+ </return>
<argument index="0" name="keep_hf_hz" type="float">
</argument>
<description>
</description>
</method>
<method name="set_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="AudioEffectDistortion.Mode">
</argument>
<description>
</description>
</method>
<method name="set_post_gain">
+ <return type="void">
+ </return>
<argument index="0" name="post_gain" type="float">
</argument>
<description>
</description>
</method>
<method name="set_pre_gain">
+ <return type="void">
+ </return>
<argument index="0" name="pre_gain" type="float">
</argument>
<description>
@@ -5791,7 +6693,7 @@
</member>
<member name="keep_hf_hz" type="float" setter="set_keep_hf_hz" getter="get_keep_hf_hz" brief="">
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="AudioEffectDistortion.Mode">
</member>
<member name="post_gain" type="float" setter="set_post_gain" getter="get_post_gain" brief="">
</member>
@@ -5822,6 +6724,8 @@
</description>
</method>
<method name="set_band_gain_db">
+ <return type="void">
+ </return>
<argument index="0" name="band_idx" type="int">
</argument>
<argument index="1" name="volume_db" type="float">
@@ -5876,7 +6780,7 @@
</description>
</method>
<method name="get_db" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioEffectFilter.FilterDB">
</return>
<description>
</description>
@@ -5894,24 +6798,32 @@
</description>
</method>
<method name="set_cutoff">
+ <return type="void">
+ </return>
<argument index="0" name="freq" type="float">
</argument>
<description>
</description>
</method>
<method name="set_db">
- <argument index="0" name="amount" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="amount" type="int" enum="AudioEffectFilter.FilterDB">
</argument>
<description>
</description>
</method>
<method name="set_gain">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_resonance">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
@@ -5921,7 +6833,7 @@
<members>
<member name="cutoff_hz" type="float" setter="set_cutoff" getter="get_cutoff" brief="">
</member>
- <member name="dB" type="int" setter="set_db" getter="get_db" brief="">
+ <member name="dB" type="int" setter="set_db" getter="get_db" brief="" enum="AudioEffectFilter.FilterDB">
</member>
<member name="gain" type="float" setter="set_gain" getter="get_gain" brief="">
</member>
@@ -5982,24 +6894,32 @@
</description>
</method>
<method name="set_ceiling_db">
+ <return type="void">
+ </return>
<argument index="0" name="ceiling" type="float">
</argument>
<description>
</description>
</method>
<method name="set_soft_clip_db">
+ <return type="void">
+ </return>
<argument index="0" name="soft_clip" type="float">
</argument>
<description>
</description>
</method>
<method name="set_soft_clip_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="soft_clip" type="float">
</argument>
<description>
</description>
</method>
<method name="set_threshold_db">
+ <return type="void">
+ </return>
<argument index="0" name="threshold" type="float">
</argument>
<description>
@@ -6062,6 +6982,8 @@
</description>
</method>
<method name="set_pan">
+ <return type="void">
+ </return>
<argument index="0" name="cpanume" type="float">
</argument>
<description>
@@ -6112,30 +7034,40 @@
</description>
</method>
<method name="set_depth">
+ <return type="void">
+ </return>
<argument index="0" name="depth" type="float">
</argument>
<description>
</description>
</method>
<method name="set_feedback">
+ <return type="void">
+ </return>
<argument index="0" name="fbk" type="float">
</argument>
<description>
</description>
</method>
<method name="set_range_max_hz">
+ <return type="void">
+ </return>
<argument index="0" name="hz" type="float">
</argument>
<description>
</description>
</method>
<method name="set_range_min_hz">
+ <return type="void">
+ </return>
<argument index="0" name="hz" type="float">
</argument>
<description>
</description>
</method>
<method name="set_rate_hz">
+ <return type="void">
+ </return>
<argument index="0" name="hz" type="float">
</argument>
<description>
@@ -6170,6 +7102,8 @@
</description>
</method>
<method name="set_pitch_scale">
+ <return type="void">
+ </return>
<argument index="0" name="rate" type="float">
</argument>
<description>
@@ -6238,48 +7172,64 @@
</description>
</method>
<method name="set_damping">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_dry">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_hpf">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_predelay_feedback">
+ <return type="void">
+ </return>
<argument index="0" name="feedback" type="float">
</argument>
<description>
</description>
</method>
<method name="set_predelay_msec">
+ <return type="void">
+ </return>
<argument index="0" name="msec" type="float">
</argument>
<description>
</description>
</method>
<method name="set_room_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="float">
</argument>
<description>
</description>
</method>
<method name="set_spread">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_wet">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
@@ -6332,18 +7282,24 @@
</description>
</method>
<method name="set_pan_pullout">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_surround">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_time_pullout">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
@@ -6370,17 +7326,21 @@
</description>
<methods>
<method name="add_bus">
+ <return type="void">
+ </return>
<argument index="0" name="at_pos" type="int" default="-1">
</argument>
<description>
</description>
</method>
<method name="add_bus_effect">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="effect" type="AudioEffect">
</argument>
- <argument index="2" name="arg2" type="int" default="-1">
+ <argument index="2" name="at_pos" type="int" default="-1">
</argument>
<description>
</description>
@@ -6408,12 +7368,10 @@
</description>
</method>
<method name="get_bus_effect_count">
+ <return type="int">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
- <argument index="1" name="arg1" type="Object">
- </argument>
- <argument index="2" name="arg2" type="int">
- </argument>
<description>
</description>
</method>
@@ -6476,7 +7434,7 @@
</description>
</method>
<method name="get_speaker_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioServer.SpeakerMode">
</return>
<description>
</description>
@@ -6516,10 +7474,14 @@
</description>
</method>
<method name="lock">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="move_bus">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<argument index="1" name="to_index" type="int">
@@ -6528,12 +7490,16 @@
</description>
</method>
<method name="remove_bus">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<description>
</description>
</method>
<method name="remove_bus_effect">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="effect_idx" type="int">
@@ -6542,6 +7508,8 @@
</description>
</method>
<method name="set_bus_bypass_effects">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -6550,12 +7518,16 @@
</description>
</method>
<method name="set_bus_count">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
</description>
</method>
<method name="set_bus_effect_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="effect_idx" type="int">
@@ -6566,12 +7538,16 @@
</description>
</method>
<method name="set_bus_layout">
+ <return type="void">
+ </return>
<argument index="0" name="bus_layout" type="AudioBusLayout">
</argument>
<description>
</description>
</method>
<method name="set_bus_mute">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -6580,6 +7556,8 @@
</description>
</method>
<method name="set_bus_name">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="name" type="String">
@@ -6588,6 +7566,8 @@
</description>
</method>
<method name="set_bus_send">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="send" type="String">
@@ -6596,6 +7576,8 @@
</description>
</method>
<method name="set_bus_solo">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -6604,6 +7586,8 @@
</description>
</method>
<method name="set_bus_volume_db">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="volume_db" type="float">
@@ -6612,6 +7596,8 @@
</description>
</method>
<method name="swap_bus_effects">
+ <return type="void">
+ </return>
<argument index="0" name="bus_idx" type="int">
</argument>
<argument index="1" name="effect_idx" type="int">
@@ -6622,6 +7608,8 @@
</description>
</method>
<method name="unlock">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -6661,6 +7649,12 @@
<description>
</description>
</method>
+ <method name="get_loop_offset" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="has_loop" qualifiers="const">
<return type="bool">
</return>
@@ -6668,23 +7662,37 @@
</description>
</method>
<method name="set_data">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="PoolByteArray">
</argument>
<description>
</description>
</method>
<method name="set_loop">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
+ <method name="set_loop_offset">
+ <return type="void">
+ </return>
+ <argument index="0" name="seconds" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="data" type="PoolByteArray" setter="set_data" getter="get_data" brief="">
</member>
<member name="loop" type="bool" setter="set_loop" getter="has_loop" brief="">
</member>
+ <member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset" brief="">
+ </member>
</members>
<constants>
</constants>
@@ -6712,7 +7720,7 @@
</description>
</method>
<method name="get_mix_target" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioStreamPlayer.MixTarget">
</return>
<description>
</description>
@@ -6724,7 +7732,7 @@
</description>
</method>
<method name="get_stream" qualifiers="const">
- <return type="Object">
+ <return type="AudioStream">
</return>
<description>
</description>
@@ -6748,48 +7756,64 @@
</description>
</method>
<method name="play">
- <argument index="0" name="from_pos" type="float" default="0">
+ <return type="void">
+ </return>
+ <argument index="0" name="from_pos" type="float" default="0.0">
</argument>
<description>
</description>
</method>
<method name="seek">
+ <return type="void">
+ </return>
<argument index="0" name="to_pos" type="float">
</argument>
<description>
</description>
</method>
<method name="set_autoplay">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_bus">
+ <return type="void">
+ </return>
<argument index="0" name="bus" type="String">
</argument>
<description>
</description>
</method>
<method name="set_mix_target">
- <argument index="0" name="mix_target" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mix_target" type="int" enum="AudioStreamPlayer.MixTarget">
</argument>
<description>
</description>
</method>
<method name="set_stream">
+ <return type="void">
+ </return>
<argument index="0" name="stream" type="AudioStream">
</argument>
<description>
</description>
</method>
<method name="set_volume_db">
+ <return type="void">
+ </return>
<argument index="0" name="volume_db" type="float">
</argument>
<description>
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -6799,7 +7823,7 @@
</member>
<member name="bus" type="String" setter="set_bus" getter="get_bus" brief="">
</member>
- <member name="mix_target" type="int" setter="set_mix_target" getter="get_mix_target" brief="">
+ <member name="mix_target" type="int" setter="set_mix_target" getter="get_mix_target" brief="" enum="AudioStreamPlayer.MixTarget">
</member>
<member name="playing" type="bool" setter="_set_playing" getter="_is_active" brief="">
</member>
@@ -6808,6 +7832,12 @@
<member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" brief="">
</member>
</members>
+ <signals>
+ <signal name="finished">
+ <description>
+ </description>
+ </signal>
+ </signals>
<constants>
</constants>
</class>
@@ -6848,7 +7878,7 @@
</description>
</method>
<method name="get_stream" qualifiers="const">
- <return type="Object">
+ <return type="AudioStream">
</return>
<description>
</description>
@@ -6872,60 +7902,80 @@
</description>
</method>
<method name="play">
- <argument index="0" name="from_pos" type="float" default="0">
+ <return type="void">
+ </return>
+ <argument index="0" name="from_pos" type="float" default="0.0">
</argument>
<description>
</description>
</method>
<method name="seek">
+ <return type="void">
+ </return>
<argument index="0" name="to_pos" type="float">
</argument>
<description>
</description>
</method>
<method name="set_area_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_attenuation">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
<method name="set_autoplay">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_bus">
+ <return type="void">
+ </return>
<argument index="0" name="bus" type="String">
</argument>
<description>
</description>
</method>
<method name="set_max_distance">
+ <return type="void">
+ </return>
<argument index="0" name="pixels" type="float">
</argument>
<description>
</description>
</method>
<method name="set_stream">
+ <return type="void">
+ </return>
<argument index="0" name="stream" type="AudioStream">
</argument>
<description>
</description>
</method>
<method name="set_volume_db">
+ <return type="void">
+ </return>
<argument index="0" name="volume_db" type="float">
</argument>
<description>
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -6948,6 +7998,12 @@
<member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" brief="">
</member>
</members>
+ <signals>
+ <signal name="finished">
+ <description>
+ </description>
+ </signal>
+ </signals>
<constants>
</constants>
</class>
@@ -6976,7 +8032,7 @@
</description>
</method>
<method name="get_attenuation_model" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioStreamPlayer3D.AttenuationModel">
</return>
<description>
</description>
@@ -6988,7 +8044,7 @@
</description>
</method>
<method name="get_doppler_tracking" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioStreamPlayer3D.DopplerTracking">
</return>
<description>
</description>
@@ -7018,7 +8074,7 @@
</description>
</method>
<method name="get_out_of_range_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioStreamPlayer3D.OutOfRangeMode">
</return>
<description>
</description>
@@ -7030,7 +8086,7 @@
</description>
</method>
<method name="get_stream" qualifiers="const">
- <return type="Object">
+ <return type="AudioStream">
</return>
<description>
</description>
@@ -7066,114 +8122,152 @@
</description>
</method>
<method name="play">
- <argument index="0" name="from_pos" type="float" default="0">
+ <return type="void">
+ </return>
+ <argument index="0" name="from_pos" type="float" default="0.0">
</argument>
<description>
</description>
</method>
<method name="seek">
+ <return type="void">
+ </return>
<argument index="0" name="to_pos" type="float">
</argument>
<description>
</description>
</method>
<method name="set_area_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_attenuation_filter_cutoff_hz">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
</description>
</method>
<method name="set_attenuation_filter_db">
+ <return type="void">
+ </return>
<argument index="0" name="db" type="float">
</argument>
<description>
</description>
</method>
<method name="set_attenuation_model">
- <argument index="0" name="model" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="model" type="int" enum="AudioStreamPlayer3D.AttenuationModel">
</argument>
<description>
</description>
</method>
<method name="set_autoplay">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_bus">
+ <return type="void">
+ </return>
<argument index="0" name="bus" type="String">
</argument>
<description>
</description>
</method>
<method name="set_doppler_tracking">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="AudioStreamPlayer3D.DopplerTracking">
</argument>
<description>
</description>
</method>
<method name="set_emission_angle">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
</description>
</method>
<method name="set_emission_angle_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_emission_angle_filter_attenuation_db">
+ <return type="void">
+ </return>
<argument index="0" name="db" type="float">
</argument>
<description>
</description>
</method>
<method name="set_max_db">
+ <return type="void">
+ </return>
<argument index="0" name="max_db" type="float">
</argument>
<description>
</description>
</method>
<method name="set_max_distance">
+ <return type="void">
+ </return>
<argument index="0" name="metres" type="float">
</argument>
<description>
</description>
</method>
<method name="set_out_of_range_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="AudioStreamPlayer3D.OutOfRangeMode">
</argument>
<description>
</description>
</method>
<method name="set_stream">
+ <return type="void">
+ </return>
<argument index="0" name="stream" type="AudioStream">
</argument>
<description>
</description>
</method>
<method name="set_unit_db">
+ <return type="void">
+ </return>
<argument index="0" name="unit_db" type="float">
</argument>
<description>
</description>
</method>
<method name="set_unit_size">
+ <return type="void">
+ </return>
<argument index="0" name="unit_size" type="float">
</argument>
<description>
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -7185,13 +8279,13 @@
</member>
<member name="attenuation_filter_db" type="float" setter="set_attenuation_filter_db" getter="get_attenuation_filter_db" brief="">
</member>
- <member name="attenuation_model" type="int" setter="set_attenuation_model" getter="get_attenuation_model" brief="">
+ <member name="attenuation_model" type="int" setter="set_attenuation_model" getter="get_attenuation_model" brief="" enum="AudioStreamPlayer3D.AttenuationModel">
</member>
<member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled" brief="">
</member>
<member name="bus" type="String" setter="set_bus" getter="get_bus" brief="">
</member>
- <member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" brief="">
+ <member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" brief="" enum="AudioStreamPlayer3D.DopplerTracking">
</member>
<member name="emission_angle_degrees" type="float" setter="set_emission_angle" getter="get_emission_angle" brief="">
</member>
@@ -7203,7 +8297,7 @@
</member>
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" brief="">
</member>
- <member name="out_of_range_mode" type="int" setter="set_out_of_range_mode" getter="get_out_of_range_mode" brief="">
+ <member name="out_of_range_mode" type="int" setter="set_out_of_range_mode" getter="get_out_of_range_mode" brief="" enum="AudioStreamPlayer3D.OutOfRangeMode">
</member>
<member name="playing" type="bool" setter="_set_playing" getter="_is_active" brief="">
</member>
@@ -7214,6 +8308,12 @@
<member name="unit_size" type="float" setter="set_unit_size" getter="get_unit_size" brief="">
</member>
</members>
+ <signals>
+ <signal name="finished">
+ <description>
+ </description>
+ </signal>
+ </signals>
<constants>
<constant name="ATTENUATION_INVERSE_DISTANCE" value="0">
</constant>
@@ -7240,7 +8340,7 @@
</description>
<methods>
<method name="get_audio_stream" qualifiers="const">
- <return type="Object">
+ <return type="AudioStream">
</return>
<description>
</description>
@@ -7252,12 +8352,16 @@
</description>
</method>
<method name="set_audio_stream">
- <argument index="0" name="stream" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="stream" type="AudioStream">
</argument>
<description>
</description>
</method>
<method name="set_random_pitch">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="float">
</argument>
<description>
@@ -7286,7 +8390,7 @@
</description>
</method>
<method name="get_format" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioStreamSample.Format">
</return>
<description>
</description>
@@ -7304,7 +8408,7 @@
</description>
</method>
<method name="get_loop_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="AudioStreamSample.LoopMode">
</return>
<description>
</description>
@@ -7322,42 +8426,56 @@
</description>
</method>
<method name="set_data">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="PoolByteArray">
</argument>
<description>
</description>
</method>
<method name="set_format">
- <argument index="0" name="format" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="AudioStreamSample.Format">
</argument>
<description>
</description>
</method>
<method name="set_loop_begin">
+ <return type="void">
+ </return>
<argument index="0" name="loop_begin" type="int">
</argument>
<description>
</description>
</method>
<method name="set_loop_end">
+ <return type="void">
+ </return>
<argument index="0" name="loop_end" type="int">
</argument>
<description>
</description>
</method>
<method name="set_loop_mode">
- <argument index="0" name="loop_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="loop_mode" type="int" enum="AudioStreamSample.LoopMode">
</argument>
<description>
</description>
</method>
<method name="set_mix_rate">
+ <return type="void">
+ </return>
<argument index="0" name="mix_rate" type="int">
</argument>
<description>
</description>
</method>
<method name="set_stereo">
+ <return type="void">
+ </return>
<argument index="0" name="stereo" type="bool">
</argument>
<description>
@@ -7367,13 +8485,13 @@
<members>
<member name="data" type="PoolByteArray" setter="set_data" getter="get_data" brief="">
</member>
- <member name="format" type="int" setter="set_format" getter="get_format" brief="">
+ <member name="format" type="int" setter="set_format" getter="get_format" brief="" enum="AudioStreamSample.Format">
</member>
<member name="loop_begin" type="int" setter="set_loop_begin" getter="get_loop_begin" brief="">
</member>
<member name="loop_end" type="int" setter="set_loop_end" getter="get_loop_end" brief="">
</member>
- <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" brief="">
+ <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" brief="" enum="AudioStreamSample.LoopMode">
</member>
<member name="mix_rate" type="int" setter="set_mix_rate" getter="get_mix_rate" brief="">
</member>
@@ -7392,7 +8510,7 @@
</description>
<methods>
<method name="get_copy_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="BackBufferCopy.CopyMode">
</return>
<description>
Return the copy mode currently applied to the BackBufferCopy (refer to constants section).
@@ -7406,13 +8524,17 @@
</description>
</method>
<method name="set_copy_mode">
- <argument index="0" name="copy_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="copy_mode" type="int" enum="BackBufferCopy.CopyMode">
</argument>
<description>
Set the copy mode of the BackBufferCopy (refer to constants section).
</description>
</method>
<method name="set_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<description>
@@ -7421,7 +8543,7 @@
</method>
</methods>
<members>
- <member name="copy_mode" type="int" setter="set_copy_mode" getter="get_copy_mode" brief="">
+ <member name="copy_mode" type="int" setter="set_copy_mode" getter="get_copy_mode" brief="" enum="BackBufferCopy.CopyMode">
</member>
<member name="rect" type="Rect2" setter="set_rect" getter="get_rect" brief="">
</member>
@@ -7447,11 +8569,15 @@
</description>
<methods>
<method name="_pressed" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
Called when button is pressed.
</description>
</method>
<method name="_toggled" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="pressed" type="bool">
</argument>
<description>
@@ -7459,34 +8585,34 @@
</description>
</method>
<method name="get_action_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="BaseButton.ActionMode">
</return>
<description>
Return the current mode of action (see [method set_action_mode]) (one of the ACTION_MODE_* constants).
</description>
</method>
<method name="get_button_group" qualifiers="const">
- <return type="Object">
+ <return type="ButtonGroup">
</return>
<description>
</description>
</method>
<method name="get_draw_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="BaseButton.DrawMode">
</return>
<description>
Return the visual state used to draw the button. This is useful mainly when implementing your own draw code by either overriding _draw() or connecting to "draw" signal. The visual state of the button is defined by the DRAW_* enum.
</description>
</method>
<method name="get_enabled_focus_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Control.FocusMode">
</return>
<description>
Returns focus access mode used when switching between enabled/disabled (see [method Control.set_focus_mode] and [method set_disabled]).
</description>
</method>
<method name="get_shortcut" qualifiers="const">
- <return type="Object">
+ <return type="ShortCut">
</return>
<description>
</description>
@@ -7520,19 +8646,25 @@
</description>
</method>
<method name="set_action_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="BaseButton.ActionMode">
</argument>
<description>
Set the current mode of action, determining when the button is considered clicked (see the ACTION_MODE_* constants).
</description>
</method>
<method name="set_button_group">
- <argument index="0" name="button_group" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="button_group" type="ButtonGroup">
</argument>
<description>
</description>
</method>
<method name="set_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="disabled" type="bool">
</argument>
<description>
@@ -7540,13 +8672,17 @@
</description>
</method>
<method name="set_enabled_focus_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Control.FocusMode">
</argument>
<description>
Sets the focus access mode to use when switching between enabled/disabled (see [method Control.set_focus_mode] and [method set_disabled]).
</description>
</method>
<method name="set_pressed">
+ <return type="void">
+ </return>
<argument index="0" name="pressed" type="bool">
</argument>
<description>
@@ -7554,12 +8690,16 @@
</description>
</method>
<method name="set_shortcut">
- <argument index="0" name="shortcut" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="shortcut" type="ShortCut">
</argument>
<description>
</description>
</method>
<method name="set_toggle_mode">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -7568,15 +8708,15 @@
</method>
</methods>
<members>
- <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" brief="">
+ <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" brief="" enum="BaseButton.ActionMode">
</member>
<member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief="">
</member>
- <member name="enabled_focus_mode" type="int" setter="set_enabled_focus_mode" getter="get_enabled_focus_mode" brief="">
+ <member name="enabled_focus_mode" type="int" setter="set_enabled_focus_mode" getter="get_enabled_focus_mode" brief="" enum="Control.FocusMode">
</member>
<member name="group" type="ButtonGroup" setter="set_button_group" getter="get_button_group" brief="">
</member>
- <member name="is_pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
+ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
</member>
<member name="shortcut" type="ShortCut" setter="set_shortcut" getter="get_shortcut" brief="">
</member>
@@ -7741,29 +8881,6 @@
Introduce an additional scaling specified by the given 3D scaling factor. Only relevant when the matrix is being used as a part of [Transform].
</description>
</method>
- <method name="set_rotation_axis_angle">
- <argument index="0" name="axis" type="Vector3">
- </argument>
- <argument index="1" name="angle" type="float">
- </argument>
- <description>
- Changes only the rotation part of the [Basis] to a rotation around given axis by phi, while preserving the scaling part (as determined by get_scale).
- </description>
- </method>
- <method name="set_rotation_euler">
- <argument index="0" name="euler" type="Vector3">
- </argument>
- <description>
- Changes only the rotation part of the [Basis] to a rotation corresponding to given Euler angles, while preserving the scaling part (as determined by get_scale).
- </description>
- </method>
- <method name="set_scale">
- <argument index="0" name="scale" type="Vector3">
- </argument>
- <description>
- Changes only the scaling part of the Basis to the specified scaling, while preserving the rotation part (as determined by get_rotation).
- </description>
- </method>
<method name="tdotx">
<return type="float">
</return>
@@ -7835,13 +8952,17 @@
</description>
<methods>
<method name="create">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="create_from_image_alpha">
- <argument index="0" name="image" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="image" type="Image">
</argument>
<description>
</description>
@@ -7867,6 +8988,8 @@
</description>
</method>
<method name="set_bit">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<argument index="1" name="bit" type="bool">
@@ -7875,6 +8998,8 @@
</description>
</method>
<method name="set_bit_rect">
+ <return type="void">
+ </return>
<argument index="0" name="p_rect" type="Rect2">
</argument>
<argument index="1" name="bit" type="bool">
@@ -7897,13 +9022,15 @@
</description>
<methods>
<method name="add_char">
+ <return type="void">
+ </return>
<argument index="0" name="character" type="int">
</argument>
<argument index="1" name="texture" type="int">
</argument>
<argument index="2" name="rect" type="Rect2">
</argument>
- <argument index="3" name="align" type="Vector2" default="Vector2(0, 0)">
+ <argument index="3" name="align" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<argument index="4" name="advance" type="float" default="-1">
</argument>
@@ -7912,6 +9039,8 @@
</description>
</method>
<method name="add_kerning_pair">
+ <return type="void">
+ </return>
<argument index="0" name="char_a" type="int">
</argument>
<argument index="1" name="char_b" type="int">
@@ -7923,6 +9052,8 @@
</description>
</method>
<method name="add_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
@@ -7930,12 +9061,14 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear all the font data.
</description>
</method>
<method name="create_from_fnt">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -7954,7 +9087,7 @@
</description>
</method>
<method name="get_fallback" qualifiers="const">
- <return type="Object">
+ <return type="BitmapFont">
</return>
<description>
</description>
@@ -7985,6 +9118,8 @@
</description>
</method>
<method name="set_ascent">
+ <return type="void">
+ </return>
<argument index="0" name="px" type="float">
</argument>
<description>
@@ -7992,18 +9127,24 @@
</description>
</method>
<method name="set_distance_field_hint">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_fallback">
- <argument index="0" name="fallback" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="fallback" type="BitmapFont">
</argument>
<description>
</description>
</method>
<method name="set_height">
+ <return type="void">
+ </return>
<argument index="0" name="px" type="float">
</argument>
<description>
@@ -8045,6 +9186,8 @@
</description>
</method>
<method name="set_bone_name">
+ <return type="void">
+ </return>
<argument index="0" name="bone_name" type="String">
</argument>
<description>
@@ -8063,6 +9206,8 @@
</description>
<methods>
<method name="add_spacer">
+ <return type="void">
+ </return>
<argument index="0" name="begin" type="bool">
</argument>
<description>
@@ -8071,14 +9216,16 @@
</description>
</method>
<method name="get_alignment" qualifiers="const">
- <return type="int">
+ <return type="int" enum="BoxContainer.AlignMode">
</return>
<description>
Return the alignment of children in the container.
</description>
</method>
<method name="set_alignment">
- <argument index="0" name="alignment" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="alignment" type="int" enum="BoxContainer.AlignMode">
</argument>
<description>
Set the alignment of children in the container(Must be one of ALIGN_BEGIN, ALIGN_CENTER or ALIGN_END).
@@ -8086,7 +9233,7 @@
</method>
</methods>
<members>
- <member name="alignment" type="int" setter="set_alignment" getter="get_alignment" brief="">
+ <member name="alignment" type="int" setter="set_alignment" getter="get_alignment" brief="" enum="BoxContainer.AlignMode">
</member>
</members>
<constants>
@@ -8117,6 +9264,8 @@
</description>
</method>
<method name="set_extents">
+ <return type="void">
+ </return>
<argument index="0" name="extents" type="Vector3">
</argument>
<description>
@@ -8161,7 +9310,7 @@
</description>
</method>
<method name="get_text_align" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Button.TextAlign">
</return>
<description>
Return the text alignment policy.
@@ -8175,6 +9324,8 @@
</description>
</method>
<method name="set_button_icon">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
@@ -8182,6 +9333,8 @@
</description>
</method>
<method name="set_clip_text">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -8189,6 +9342,8 @@
</description>
</method>
<method name="set_flat">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -8196,6 +9351,8 @@
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -8203,7 +9360,9 @@
</description>
</method>
<method name="set_text_align">
- <argument index="0" name="align" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="align" type="int" enum="Button.TextAlign">
</argument>
<description>
Set the text alignment policy, using one of the ALIGN_* constants.
@@ -8211,7 +9370,7 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_text_align" getter="get_text_align" brief="">
+ <member name="align" type="int" setter="set_text_align" getter="get_text_align" brief="" enum="Button.TextAlign">
</member>
<member name="clip_text" type="bool" setter="set_clip_text" getter="get_clip_text" brief="">
</member>
@@ -8290,6 +9449,8 @@
</description>
<methods>
<method name="clear_current">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -8307,7 +9468,7 @@
</description>
</method>
<method name="get_doppler_tracking" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Camera.DopplerTracking">
</return>
<description>
</description>
@@ -8331,13 +9492,13 @@
</description>
</method>
<method name="get_keep_aspect_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Camera.KeepAspect">
</return>
<description>
</description>
</method>
<method name="get_projection" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Camera.Projection">
</return>
<description>
</description>
@@ -8382,6 +9543,8 @@
</description>
</method>
<method name="make_current">
+ <return type="void">
+ </return>
<description>
Make this camera the current Camera for the [Viewport] (see class description). If the Camera Node is outside the scene tree, it will attempt to become current once it's added.
</description>
@@ -8421,36 +9584,48 @@
</description>
</method>
<method name="set_cull_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_doppler_tracking">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Camera.DopplerTracking">
</argument>
<description>
</description>
</method>
<method name="set_environment">
+ <return type="void">
+ </return>
<argument index="0" name="env" type="Environment">
</argument>
<description>
</description>
</method>
<method name="set_h_offset">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="float">
</argument>
<description>
</description>
</method>
<method name="set_keep_aspect_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Camera.KeepAspect">
</argument>
<description>
</description>
</method>
<method name="set_orthogonal">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="float">
</argument>
<argument index="1" name="z_near" type="float">
@@ -8462,6 +9637,8 @@
</description>
</method>
<method name="set_perspective">
+ <return type="void">
+ </return>
<argument index="0" name="fov" type="float">
</argument>
<argument index="1" name="z_near" type="float">
@@ -8473,6 +9650,8 @@
</description>
</method>
<method name="set_v_offset">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="float">
</argument>
<description>
@@ -8517,21 +9696,27 @@
</description>
<methods>
<method name="align">
+ <return type="void">
+ </return>
<description>
Align the camera to the tracked node
</description>
</method>
<method name="clear_current">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="force_update_scroll">
+ <return type="void">
+ </return>
<description>
Force the camera to update scroll immediately.
</description>
</method>
<method name="get_anchor_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Camera2D.AnchorMode">
</return>
<description>
</description>
@@ -8550,7 +9735,7 @@
</description>
</method>
<method name="get_custom_viewport" qualifiers="const">
- <return type="Viewport">
+ <return type="Node">
</return>
<description>
</description>
@@ -8558,7 +9743,7 @@
<method name="get_drag_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return the margins needed to drag the camera (see [method set_drag_margin]).
@@ -8579,7 +9764,7 @@
<method name="get_limit" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return the scrolling limit in pixels.
@@ -8660,30 +9845,40 @@
</description>
</method>
<method name="make_current">
+ <return type="void">
+ </return>
<description>
Make this the current 2D camera for the scene (viewport and layer), in case there's many cameras in the scene.
</description>
</method>
<method name="reset_smoothing">
+ <return type="void">
+ </return>
<description>
Set the camera's position immediately to its current smoothing destination.
This has no effect if smoothing is disabled.
</description>
</method>
<method name="set_anchor_mode">
- <argument index="0" name="anchor_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="anchor_mode" type="int" enum="Camera2D.AnchorMode">
</argument>
<description>
</description>
</method>
<method name="set_custom_viewport">
- <argument index="0" name="viewport" type="Viewport">
+ <return type="void">
+ </return>
+ <argument index="0" name="viewport" type="Node">
</argument>
<description>
</description>
</method>
<method name="set_drag_margin">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="drag_margin" type="float">
</argument>
@@ -8692,31 +9887,41 @@
</description>
</method>
<method name="set_enable_follow_smoothing">
+ <return type="void">
+ </return>
<argument index="0" name="follow_smoothing" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_follow_smoothing">
+ <return type="void">
+ </return>
<argument index="0" name="follow_smoothing" type="float">
</argument>
<description>
</description>
</method>
<method name="set_h_drag_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_h_offset">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="float">
</argument>
<description>
</description>
</method>
<method name="set_limit">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="limit" type="int">
</argument>
@@ -8725,12 +9930,16 @@
</description>
</method>
<method name="set_limit_drawing_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="limit_drawing_enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_limit_smoothing_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="limit_smoothing_enabled" type="bool">
</argument>
<description>
@@ -8739,12 +9948,16 @@
</description>
</method>
<method name="set_margin_drawing_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="margin_drawing_enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -8752,30 +9965,40 @@
</description>
</method>
<method name="set_rotating">
+ <return type="void">
+ </return>
<argument index="0" name="rotating" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_screen_drawing_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="screen_drawing_enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_v_drag_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_v_offset">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="float">
</argument>
<description>
</description>
</method>
<method name="set_zoom">
+ <return type="void">
+ </return>
<argument index="0" name="zoom" type="Vector2">
</argument>
<description>
@@ -8783,7 +10006,7 @@
</method>
</methods>
<members>
- <member name="anchor_mode" type="int" setter="set_anchor_mode" getter="get_anchor_mode" brief="">
+ <member name="anchor_mode" type="int" setter="set_anchor_mode" getter="get_anchor_mode" brief="" enum="Camera2D.AnchorMode">
</member>
<member name="current" type="bool" setter="_set_current" getter="is_current" brief="">
</member>
@@ -8846,6 +10069,8 @@
</description>
<methods>
<method name="_draw" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
Called (if exists) to draw the canvas item.
</description>
@@ -8861,13 +10086,15 @@
</argument>
<argument index="3" name="next" type="String">
</argument>
- <argument index="4" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="4" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<description>
Draw a string character using a custom font. Returns the advance, depending on the char width and kerning with an optional next char.
</description>
</method>
<method name="draw_circle">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<argument index="1" name="radius" type="float">
@@ -8879,28 +10106,34 @@
</description>
</method>
<method name="draw_colored_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<argument index="1" name="color" type="Color">
</argument>
- <argument index="2" name="uvs" type="PoolVector2Array" default="PoolVector2Array([])">
+ <argument index="2" name="uvs" type="PoolVector2Array" default="PoolVector2Array( )">
+ </argument>
+ <argument index="3" name="texture" type="Texture" default="null">
</argument>
- <argument index="3" name="texture" type="Texture" default="NULL">
+ <argument index="4" name="normal_map" type="Texture" default="null">
</argument>
- <argument index="4" name="normal_map" type="Texture" default="NULL">
+ <argument index="5" name="antialiased" type="bool" default="false">
</argument>
<description>
Draw a colored polygon of any amount of points, convex or concave.
</description>
</method>
<method name="draw_line">
+ <return type="void">
+ </return>
<argument index="0" name="from" type="Vector2">
</argument>
<argument index="1" name="to" type="Vector2">
</argument>
<argument index="2" name="color" type="Color">
</argument>
- <argument index="3" name="width" type="float" default="1">
+ <argument index="3" name="width" type="float" default="1.0">
</argument>
<argument index="4" name="antialiased" type="bool" default="false">
</argument>
@@ -8909,26 +10142,32 @@
</description>
</method>
<method name="draw_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<argument index="1" name="colors" type="PoolColorArray">
</argument>
- <argument index="2" name="uvs" type="PoolVector2Array" default="PoolVector2Array([])">
+ <argument index="2" name="uvs" type="PoolVector2Array" default="PoolVector2Array( )">
</argument>
- <argument index="3" name="texture" type="Texture" default="NULL">
+ <argument index="3" name="texture" type="Texture" default="null">
</argument>
- <argument index="4" name="normal_map" type="Texture" default="NULL">
+ <argument index="4" name="normal_map" type="Texture" default="null">
+ </argument>
+ <argument index="5" name="antialiased" type="bool" default="false">
</argument>
<description>
Draw a polygon of any amount of points, convex or concave.
</description>
</method>
<method name="draw_polyline">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<argument index="1" name="color" type="Color">
</argument>
- <argument index="2" name="width" type="float" default="1">
+ <argument index="2" name="width" type="float" default="1.0">
</argument>
<argument index="3" name="antialiased" type="bool" default="false">
</argument>
@@ -8936,11 +10175,13 @@
</description>
</method>
<method name="draw_polyline_colors">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<argument index="1" name="colors" type="PoolColorArray">
</argument>
- <argument index="2" name="width" type="float" default="1">
+ <argument index="2" name="width" type="float" default="1.0">
</argument>
<argument index="3" name="antialiased" type="bool" default="false">
</argument>
@@ -8948,23 +10189,27 @@
</description>
</method>
<method name="draw_primitive">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<argument index="1" name="colors" type="PoolColorArray">
</argument>
<argument index="2" name="uvs" type="PoolVector2Array">
</argument>
- <argument index="3" name="texture" type="Texture" default="NULL">
+ <argument index="3" name="texture" type="Texture" default="null">
</argument>
- <argument index="4" name="width" type="float" default="1">
+ <argument index="4" name="width" type="float" default="1.0">
</argument>
- <argument index="5" name="normal_map" type="Texture" default="NULL">
+ <argument index="5" name="normal_map" type="Texture" default="null">
</argument>
<description>
Draw a custom primitive, 1 point for a point, 2 points for a line, 3 points for a triangle and 4 points for a quad.
</description>
</method>
<method name="draw_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<argument index="1" name="color" type="Color">
@@ -8976,6 +10221,8 @@
</description>
</method>
<method name="draw_set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<argument index="1" name="rot" type="float">
@@ -8987,19 +10234,23 @@
</description>
</method>
<method name="draw_set_transform_matrix">
+ <return type="void">
+ </return>
<argument index="0" name="xform" type="Transform2D">
</argument>
<description>
</description>
</method>
<method name="draw_string">
+ <return type="void">
+ </return>
<argument index="0" name="font" type="Font">
</argument>
<argument index="1" name="pos" type="Vector2">
</argument>
<argument index="2" name="text" type="String">
</argument>
- <argument index="3" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="4" name="clip_w" type="int" default="-1">
</argument>
@@ -9008,6 +10259,8 @@
</description>
</method>
<method name="draw_style_box">
+ <return type="void">
+ </return>
<argument index="0" name="style_box" type="StyleBox">
</argument>
<argument index="1" name="rect" type="Rect2">
@@ -9017,47 +10270,53 @@
</description>
</method>
<method name="draw_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="pos" type="Vector2">
</argument>
- <argument index="2" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="2" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
- <argument index="3" name="normal_map" type="Texture" default="NULL">
+ <argument index="3" name="normal_map" type="Texture" default="null">
</argument>
<description>
Draw a texture at a given position.
</description>
</method>
<method name="draw_texture_rect">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="rect" type="Rect2">
</argument>
<argument index="2" name="tile" type="bool">
</argument>
- <argument index="3" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
- <argument index="5" name="normal_map" type="Texture" default="NULL">
+ <argument index="5" name="normal_map" type="Texture" default="null">
</argument>
<description>
Draw a textured rectangle at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture.
</description>
</method>
<method name="draw_texture_rect_region">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="rect" type="Rect2">
</argument>
<argument index="2" name="src_rect" type="Rect2">
</argument>
- <argument index="3" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
- <argument index="5" name="normal_map" type="Texture" default="NULL">
+ <argument index="5" name="normal_map" type="Texture" default="null">
</argument>
<argument index="6" name="clip_uv" type="bool" default="true">
</argument>
@@ -9073,6 +10332,8 @@
</description>
</method>
<method name="edit_rotate">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
@@ -9080,12 +10341,16 @@
</description>
</method>
<method name="edit_set_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<description>
</description>
</method>
<method name="edit_set_state">
+ <return type="void">
+ </return>
<argument index="0" name="state" type="Variant">
</argument>
<description>
@@ -9212,13 +10477,15 @@
</description>
</method>
<method name="get_world_2d" qualifiers="const">
- <return type="Object">
+ <return type="World2D">
</return>
<description>
Get the [World2D] where this item is in.
</description>
</method>
<method name="hide">
+ <return type="void">
+ </return>
<description>
Hide the CanvasItem currently visible.
</description>
@@ -9271,14 +10538,16 @@
</description>
</method>
<method name="make_input_local" qualifiers="const">
- <return type="Object">
+ <return type="InputEvent">
</return>
- <argument index="0" name="event" type="Object">
+ <argument index="0" name="event" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="set_as_toplevel">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -9286,6 +10555,8 @@
</description>
</method>
<method name="set_draw_behind_parent">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -9293,6 +10564,8 @@
</description>
</method>
<method name="set_light_mask">
+ <return type="void">
+ </return>
<argument index="0" name="light_mask" type="int">
</argument>
<description>
@@ -9300,6 +10573,8 @@
</description>
</method>
<method name="set_material">
+ <return type="void">
+ </return>
<argument index="0" name="material" type="Material">
</argument>
<description>
@@ -9307,6 +10582,8 @@
</description>
</method>
<method name="set_modulate">
+ <return type="void">
+ </return>
<argument index="0" name="modulate" type="Color">
</argument>
<description>
@@ -9314,18 +10591,24 @@
</description>
</method>
<method name="set_notify_local_transform">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_notify_transform">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_self_modulate">
+ <return type="void">
+ </return>
<argument index="0" name="self_modulate" type="Color">
</argument>
<description>
@@ -9333,6 +10616,8 @@
</description>
</method>
<method name="set_use_parent_material">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -9340,7 +10625,9 @@
</description>
</method>
<method name="set_visible">
- <argument index="0" name="arg0" type="bool">
+ <return type="void">
+ </return>
+ <argument index="0" name="visible" type="bool">
</argument>
<description>
Set whether this item should be visible or not.
@@ -9348,11 +10635,15 @@
</description>
</method>
<method name="show">
+ <return type="void">
+ </return>
<description>
Show the CanvasItem currently hidden.
</description>
</method>
<method name="update">
+ <return type="void">
+ </return>
<description>
Queue the CanvasItem for update. [code]NOTIFICATION_DRAW[/code] will be called on idle time to request redraw.
</description>
@@ -9361,7 +10652,7 @@
<members>
<member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" brief="">
</member>
- <member name="material" type="ShaderMaterial,CanvasItemMaterial" setter="set_material" getter="get_material" brief="">
+ <member name="material" type="Material" setter="set_material" getter="get_material" brief="">
</member>
<member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" brief="">
</member>
@@ -9414,19 +10705,19 @@
<constant name="BLEND_MODE_PREMULT_ALPHA" value="4">
Mix blending mode. Colors are assumed to be premultiplied by the alpha (opacity) value.
</constant>
- <constant name="NOTIFICATION_DRAW" value="30">
+ <constant name="NOTIFICATION_DRAW" value="30" enum="">
CanvasItem is requested to draw.
</constant>
- <constant name="NOTIFICATION_VISIBILITY_CHANGED" value="31">
+ <constant name="NOTIFICATION_VISIBILITY_CHANGED" value="31" enum="">
Canvas item visibility has changed.
</constant>
- <constant name="NOTIFICATION_ENTER_CANVAS" value="32">
+ <constant name="NOTIFICATION_ENTER_CANVAS" value="32" enum="">
Canvas item has entered the canvas.
</constant>
- <constant name="NOTIFICATION_EXIT_CANVAS" value="33">
+ <constant name="NOTIFICATION_EXIT_CANVAS" value="33" enum="">
Canvas item has exited the canvas.
</constant>
- <constant name="NOTIFICATION_TRANSFORM_CHANGED" value="29">
+ <constant name="NOTIFICATION_TRANSFORM_CHANGED" value="29" enum="">
Canvas item transform has changed. Only received if requested.
</constant>
</constants>
@@ -9438,34 +10729,38 @@
</description>
<methods>
<method name="get_blend_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="CanvasItemMaterial.BlendMode">
</return>
<description>
</description>
</method>
<method name="get_light_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="CanvasItemMaterial.LightMode">
</return>
<description>
</description>
</method>
<method name="set_blend_mode">
- <argument index="0" name="blend_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="blend_mode" type="int" enum="CanvasItemMaterial.BlendMode">
</argument>
<description>
</description>
</method>
<method name="set_light_mode">
- <argument index="0" name="light_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="light_mode" type="int" enum="CanvasItemMaterial.LightMode">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" brief="">
+ <member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" brief="" enum="CanvasItemMaterial.BlendMode">
</member>
- <member name="light_mode" type="int" setter="set_light_mode" getter="get_light_mode" brief="">
+ <member name="light_mode" type="int" setter="set_light_mode" getter="get_light_mode" brief="" enum="CanvasItemMaterial.LightMode">
</member>
</members>
<constants>
@@ -9496,7 +10791,7 @@
</description>
<methods>
<method name="get_custom_viewport" qualifiers="const">
- <return type="Viewport">
+ <return type="Node">
</return>
<description>
</description>
@@ -9551,12 +10846,16 @@
</description>
</method>
<method name="set_custom_viewport">
- <argument index="0" name="viewport" type="Viewport">
+ <return type="void">
+ </return>
+ <argument index="0" name="viewport" type="Node">
</argument>
<description>
</description>
</method>
<method name="set_layer">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
@@ -9564,6 +10863,8 @@
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -9571,6 +10872,8 @@
</description>
</method>
<method name="set_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
@@ -9578,6 +10881,8 @@
</description>
</method>
<method name="set_rotationd">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
@@ -9585,6 +10890,8 @@
</description>
</method>
<method name="set_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector2">
</argument>
<description>
@@ -9592,6 +10899,8 @@
</description>
</method>
<method name="set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="transform" type="Transform2D">
</argument>
<description>
@@ -9628,6 +10937,8 @@
</description>
</method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -9673,24 +10984,32 @@
</description>
</method>
<method name="set_mid_height">
+ <return type="void">
+ </return>
<argument index="0" name="mid_height" type="float">
</argument>
<description>
</description>
</method>
<method name="set_radial_segments">
+ <return type="void">
+ </return>
<argument index="0" name="segments" type="int">
</argument>
<description>
</description>
</method>
<method name="set_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
<method name="set_rings">
+ <return type="void">
+ </return>
<argument index="0" name="rings" type="int">
</argument>
<description>
@@ -9733,6 +11052,8 @@
</description>
</method>
<method name="set_height">
+ <return type="void">
+ </return>
<argument index="0" name="height" type="float">
</argument>
<description>
@@ -9740,6 +11061,8 @@
</description>
</method>
<method name="set_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
@@ -9779,6 +11102,8 @@
</description>
</method>
<method name="set_height">
+ <return type="void">
+ </return>
<argument index="0" name="height" type="float">
</argument>
<description>
@@ -9786,6 +11111,8 @@
</description>
</method>
<method name="set_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
@@ -9818,6 +11145,8 @@
</description>
</method>
<method name="set_use_top_left">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -9936,6 +11265,8 @@
</description>
</method>
<method name="set_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
@@ -10083,7 +11414,7 @@
</description>
</method>
<method name="class_set_property" qualifiers="const">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="object" type="Object">
</argument>
@@ -10153,6 +11484,8 @@
</description>
<methods>
<method name="_input_event" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="camera" type="Object">
</argument>
<argument index="1" name="event" type="InputEvent">
@@ -10166,12 +11499,6 @@
<description>
</description>
</method>
- <method name="get_capture_input_on_drag" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
<method name="create_shape_owner">
<return type="int">
</return>
@@ -10181,6 +11508,12 @@
Creates new holder for the shapes. Argument is a [CollisionShape] node. It will return owner_id which usually you will want to save for later use.
</description>
</method>
+ <method name="get_capture_input_on_drag" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_rid" qualifiers="const">
<return type="RID">
</return>
@@ -10194,14 +11527,80 @@
Shape owner is a node which is holding concrete shape resources. This method will return an array which is holding an integer numbers that are representing unique ID of each owner. You can use those ids when you are using others shape_owner methods.
</description>
</method>
+ <method name="is_ray_pickable" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_shape_owner_disabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="remove_shape_owner">
+ <return type="void">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_capture_input_on_drag">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_ray_pickable">
+ <return type="void">
+ </return>
+ <argument index="0" name="ray_pickable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_find_owner" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="shape_index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_owner_add_shape">
+ <return type="void">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape" type="Shape">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="shape_owner_clear_shapes">
+ <return type="void">
+ </return>
<argument index="0" name="owner_id" type="int">
</argument>
<description>
Will remove all the shapes associated with given owner.
</description>
</method>
- <method name="shape_owner_get_shape">
+ <method name="shape_owner_get_owner" qualifiers="const">
+ <return type="Object">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_owner_get_shape" qualifiers="const">
<return type="Shape">
</return>
<argument index="0" name="owner_id" type="int">
@@ -10212,7 +11611,7 @@
Will return a [Shape]. First argument owner_id is an integer that can be obtained from [method get_shape_owners]. Shape_id is a position of the shape inside owner; it's a value in range from 0 to [method shape_owner_get_shape_count].
</description>
</method>
- <method name="shape_owner_get_shape_count">
+ <method name="shape_owner_get_shape_count" qualifiers="const">
<return type="int">
</return>
<argument index="0" name="owner_id" type="int">
@@ -10221,7 +11620,17 @@
Returns number of shapes to which given owner is associated to.
</description>
</method>
- <method name="shape_owner_get_transform">
+ <method name="shape_owner_get_shape_index" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_owner_get_transform" qualifiers="const">
<return type="Transform">
</return>
<argument index="0" name="owner_id" type="int">
@@ -10231,6 +11640,8 @@
</description>
</method>
<method name="shape_owner_remove_shape">
+ <return type="void">
+ </return>
<argument index="0" name="owner_id" type="int">
</argument>
<argument index="1" name="shape_id" type="int">
@@ -10239,20 +11650,22 @@
Removes related shape from the owner.
</description>
</method>
- <method name="is_ray_pickable" qualifiers="const">
- <return type="bool">
+ <method name="shape_owner_set_disabled">
+ <return type="void">
</return>
- <description>
- </description>
- </method>
- <method name="set_capture_input_on_drag">
- <argument index="0" name="enable" type="bool">
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="disabled" type="bool">
</argument>
<description>
</description>
</method>
- <method name="set_ray_pickable">
- <argument index="0" name="ray_pickable" type="bool">
+ <method name="shape_owner_set_transform">
+ <return type="void">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="transform" type="Transform">
</argument>
<description>
</description>
@@ -10300,6 +11713,8 @@
</description>
<methods>
<method name="_input_event" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="viewport" type="Object">
</argument>
<argument index="1" name="event" type="InputEvent">
@@ -10332,14 +11747,82 @@
Shape owner is a node which is holding concrete shape resources. This method will return an array which is holding an integer numbers that are representing unique ID of each owner. You can use those ids when you are using others shape_owner methods.
</description>
</method>
+ <method name="is_pickable" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ Return whether this object is pickable.
+ </description>
+ </method>
+ <method name="is_shape_owner_disabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_shape_owner_one_way_collision_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="remove_shape_owner">
+ <return type="void">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_pickable">
+ <return type="void">
+ </return>
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ Set whether this object is pickable. A pickable object can detect the mouse pointer enter/leave it and, if the mouse is inside it, report input events.
+ </description>
+ </method>
+ <method name="shape_find_owner" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="shape_index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_owner_add_shape">
+ <return type="void">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape" type="Shape2D">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="shape_owner_clear_shapes">
+ <return type="void">
+ </return>
<argument index="0" name="owner_id" type="int">
</argument>
<description>
Will remove all the shapes associated with given owner.
</description>
</method>
- <method name="shape_owner_get_shape">
+ <method name="shape_owner_get_owner" qualifiers="const">
+ <return type="Object">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_owner_get_shape" qualifiers="const">
<return type="Shape2D">
</return>
<argument index="0" name="owner_id" type="int">
@@ -10350,7 +11833,7 @@
Will return a [Shape2D]. First argument owner_id is an integer that can be obtained from [method get_shape_owners]. Shape_id is a position of the shape inside owner; it's a value in range from 0 to [method shape_owner_get_shape_count].
</description>
</method>
- <method name="shape_owner_get_shape_count">
+ <method name="shape_owner_get_shape_count" qualifiers="const">
<return type="int">
</return>
<argument index="0" name="owner_id" type="int">
@@ -10359,7 +11842,17 @@
Returns number of shapes to which given owner is associated to.
</description>
</method>
- <method name="shape_owner_get_transform">
+ <method name="shape_owner_get_shape_index" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_owner_get_transform" qualifiers="const">
<return type="Transform2D">
</return>
<argument index="0" name="owner_id" type="int">
@@ -10369,6 +11862,8 @@
</description>
</method>
<method name="shape_owner_remove_shape">
+ <return type="void">
+ </return>
<argument index="0" name="owner_id" type="int">
</argument>
<argument index="1" name="shape_id" type="int">
@@ -10377,18 +11872,34 @@
Removes related shape from the owner.
</description>
</method>
- <method name="is_pickable" qualifiers="const">
- <return type="bool">
+ <method name="shape_owner_set_disabled">
+ <return type="void">
</return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="disabled" type="bool">
+ </argument>
<description>
- Return whether this object is pickable.
</description>
</method>
- <method name="set_pickable">
- <argument index="0" name="enabled" type="bool">
+ <method name="shape_owner_set_one_way_collision">
+ <return type="void">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shape_owner_set_transform">
+ <return type="void">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="transform" type="Transform2D">
</argument>
<description>
- Set whether this object is pickable. A pickable object can detect the mouse pointer enter/leave it and, if the mouse is inside it, report input events.
</description>
</method>
</methods>
@@ -10446,18 +11957,24 @@
</description>
</method>
<method name="set_depth">
+ <return type="void">
+ </return>
<argument index="0" name="depth" type="float">
</argument>
<description>
</description>
</method>
<method name="set_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="disabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="polygon" type="PoolVector2Array">
</argument>
<description>
@@ -10484,7 +12001,7 @@
</description>
<methods>
<method name="get_build_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="CollisionPolygon2D.BuildMode">
</return>
<description>
Return whether the polygon is a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
@@ -10510,25 +12027,33 @@
</description>
</method>
<method name="set_build_mode">
- <argument index="0" name="build_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="build_mode" type="int" enum="CollisionPolygon2D.BuildMode">
</argument>
<description>
Set whether the polygon is to be a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
</description>
</method>
<method name="set_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="disabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_one_way_collision">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="polygon" type="PoolVector2Array">
</argument>
<description>
@@ -10538,7 +12063,7 @@
</method>
</methods>
<members>
- <member name="build_mode" type="int" setter="set_build_mode" getter="get_build_mode" brief="">
+ <member name="build_mode" type="int" setter="set_build_mode" getter="get_build_mode" brief="" enum="CollisionPolygon2D.BuildMode">
</member>
<member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief="">
</member>
@@ -10557,7 +12082,7 @@
</description>
<methods>
<method name="get_shape" qualifiers="const">
- <return type="Object">
+ <return type="Shape">
</return>
<description>
</description>
@@ -10569,23 +12094,31 @@
</description>
</method>
<method name="make_convex_from_brothers">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="resource_changed">
- <argument index="0" name="resource" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="resource" type="Resource">
</argument>
<description>
</description>
</method>
<method name="set_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_shape">
- <argument index="0" name="shape" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="shape" type="Shape">
</argument>
<description>
</description>
@@ -10609,7 +12142,7 @@
</description>
<methods>
<method name="get_shape" qualifiers="const">
- <return type="Object">
+ <return type="Shape2D">
</return>
<description>
Return this shape's [Shape2D].
@@ -10628,19 +12161,25 @@
</description>
</method>
<method name="set_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="disabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_one_way_collision">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_shape">
- <argument index="0" name="shape" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="shape" type="Shape2D">
</argument>
<description>
Set this shape's [Shape2D]. This will not appear as a node, but can be directly edited as a property.
@@ -10824,7 +12363,9 @@
</description>
<methods>
<method name="add_preset">
- <argument index="0" name="arg0" type="Color">
+ <return type="void">
+ </return>
+ <argument index="0" name="color" type="Color">
</argument>
<description>
Adds the current selected to color to a list of colors (presets), the presets will be displayed in the color picker and the user will be able to select them, notice that the presets list is only for this color picker.
@@ -10852,6 +12393,8 @@
</description>
</method>
<method name="set_edit_alpha">
+ <return type="void">
+ </return>
<argument index="0" name="show" type="bool">
</argument>
<description>
@@ -10859,6 +12402,8 @@
</description>
</method>
<method name="set_pick_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -10866,6 +12411,8 @@
</description>
</method>
<method name="set_raw_mode">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="bool">
</argument>
<description>
@@ -10933,6 +12480,8 @@
</description>
</method>
<method name="set_edit_alpha">
+ <return type="void">
+ </return>
<argument index="0" name="show" type="bool">
</argument>
<description>
@@ -10940,6 +12489,8 @@
</description>
</method>
<method name="set_pick_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -11001,6 +12552,8 @@
</description>
</method>
<method name="set_frame_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -11030,6 +12583,8 @@
</description>
</method>
<method name="set_faces">
+ <return type="void">
+ </return>
<argument index="0" name="faces" type="PoolVector3Array">
</argument>
<description>
@@ -11057,6 +12612,8 @@
</description>
</method>
<method name="set_segments">
+ <return type="void">
+ </return>
<argument index="0" name="segments" type="PoolVector2Array">
</argument>
<description>
@@ -11080,13 +12637,15 @@
<method name="get_param" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="ConeTwistJoint.Param">
</argument>
<description>
</description>
</method>
<method name="set_param">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="ConeTwistJoint.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -11143,6 +12702,8 @@
</description>
<methods>
<method name="erase_section">
+ <return type="void">
+ </return>
<argument index="0" name="section" type="String">
</argument>
<description>
@@ -11171,7 +12732,7 @@
</argument>
<argument index="1" name="key" type="String">
</argument>
- <argument index="2" name="default" type="Variant" default="NULL">
+ <argument index="2" name="default" type="Variant" default="null">
</argument>
<description>
Return the current value for the specified section and key. If the section and/or the key do not exist, the method returns the value of the optional [i]default[/i] argument (and thus [code]NULL[/code] if not specified).
@@ -11198,7 +12759,7 @@
</description>
</method>
<method name="load">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -11207,7 +12768,7 @@
</description>
</method>
<method name="save">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -11217,6 +12778,8 @@
</description>
</method>
<method name="set_value">
+ <return type="void">
+ </return>
<argument index="0" name="section" type="String">
</argument>
<argument index="1" name="key" type="String">
@@ -11260,6 +12823,8 @@
</description>
<methods>
<method name="fit_child_in_rect">
+ <return type="void">
+ </return>
<argument index="0" name="child" type="Control">
</argument>
<argument index="1" name="rect" type="Rect2">
@@ -11269,6 +12834,8 @@
</description>
</method>
<method name="queue_sort">
+ <return type="void">
+ </return>
<description>
Queue resort of the contained children. This is called automatically anyway, but can be called upon request.
</description>
@@ -11282,7 +12849,7 @@
</signal>
</signals>
<constants>
- <constant name="NOTIFICATION_SORT_CHILDREN" value="50">
+ <constant name="NOTIFICATION_SORT_CHILDREN" value="50" enum="">
Notification for when sorting the children, it must be obeyed immediately.
</constant>
</constants>
@@ -11309,17 +12876,23 @@
</description>
</method>
<method name="_gui_input" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="accept_event">
+ <return type="void">
+ </return>
<description>
Handles the event, no other control will receive it and it will not be sent to nodes waiting on [method Node._unhandled_input] or [method Node._unhandled_key_input].
</description>
</method>
<method name="add_color_override">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="color" type="Color">
@@ -11328,6 +12901,8 @@
</description>
</method>
<method name="add_constant_override">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="constant" type="int">
@@ -11337,6 +12912,8 @@
</description>
</method>
<method name="add_font_override">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="font" type="Font">
@@ -11346,6 +12923,8 @@
</description>
</method>
<method name="add_icon_override">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="texture" type="Texture">
@@ -11355,6 +12934,8 @@
</description>
</method>
<method name="add_shader_override">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="shader" type="Shader">
@@ -11363,6 +12944,8 @@
</description>
</method>
<method name="add_style_override">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="stylebox" type="StyleBox">
@@ -11382,6 +12965,8 @@
</description>
</method>
<method name="drop_data" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<argument index="1" name="data" type="Variant">
@@ -11390,17 +12975,19 @@
</description>
</method>
<method name="force_drag">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="Variant">
</argument>
- <argument index="1" name="preview" type="Object">
+ <argument index="1" name="preview" type="Control">
</argument>
<description>
</description>
</method>
<method name="get_anchor" qualifiers="const">
- <return type="int">
+ <return type="float">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return the anchor type (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) for a given margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM).
@@ -11439,9 +13026,9 @@
</description>
</method>
<method name="get_cursor_shape" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Control.CursorShape">
</return>
- <argument index="0" name="pos" type="Vector2" default="Vector2(0, 0)">
+ <argument index="0" name="pos" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
Return the cursor shape at a certain position in the control.
@@ -11454,7 +13041,7 @@
</description>
</method>
<method name="get_default_cursor_shape" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Control.CursorShape">
</return>
<description>
Return the default cursor shape for this control. See enum CURSOR_* for the list of shapes.
@@ -11476,7 +13063,7 @@
</description>
</method>
<method name="get_focus_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Control.FocusMode">
</return>
<description>
Returns the focus access mode for the control (FOCUS_NONE, FOCUS_CLICK, FOCUS_ALL) (see [method set_focus_mode]).
@@ -11485,7 +13072,7 @@
<method name="get_focus_neighbour" qualifiers="const">
<return type="NodePath">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return the forced neighbour for moving the input focus to. When pressing TAB or directional/joypad directions focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function.
@@ -11523,7 +13110,7 @@
</description>
</method>
<method name="get_h_grow_direction" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Control.GrowDirection">
</return>
<description>
</description>
@@ -11548,7 +13135,7 @@
<method name="get_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return a margin offset. Margin can be one of (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Offset value being returned depends on the anchor mode.
@@ -11562,7 +13149,7 @@
</description>
</method>
<method name="get_mouse_filter" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Control.MouseFilter">
</return>
<description>
Return when the control is ignoring mouse events (even touchpad events send mouse events).
@@ -11654,14 +13241,14 @@
<method name="get_tooltip" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="atpos" type="Vector2" default="Vector2(0, 0)">
+ <argument index="0" name="atpos" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
Return the tooltip, which will appear when the cursor is resting over this control.
</description>
</method>
<method name="get_v_grow_direction" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Control.GrowDirection">
</return>
<description>
</description>
@@ -11674,10 +13261,14 @@
</description>
</method>
<method name="grab_click_focus">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="grab_focus">
+ <return type="void">
+ </return>
<description>
Steal the focus from another control and become the focused control (see [method set_focus_mode]).
</description>
@@ -11762,6 +13353,8 @@
</description>
</method>
<method name="has_point" qualifiers="virtual">
+ <return type="bool">
+ </return>
<argument index="0" name="point" type="Vector2">
</argument>
<description>
@@ -11792,38 +13385,59 @@
</description>
</method>
<method name="minimum_size_changed">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="release_focus">
+ <return type="void">
+ </return>
<description>
Give up the focus, no other control will be able to receive keyboard input.
</description>
</method>
<method name="set_anchor">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
- <argument index="1" name="anchor_mode" type="int">
+ <argument index="1" name="anchor" type="float">
</argument>
<argument index="2" name="keep_margin" type="bool" default="false">
</argument>
+ <argument index="3" name="push_opposite_anchor" type="bool" default="true">
+ </argument>
<description>
- Change the anchor (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) type for a margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Changing the anchor mode converts the current margin offset from the previous anchor mode to the new one, so margin offsets ([method set_margin]) must be done after setting anchors, or at the same time ([method set_anchor_and_margin])
- Additionally, [code]keep_margin[/code] controls whether margins should be left the same, or changed to keep the same position and size on-screen.
</description>
</method>
<method name="set_anchor_and_margin">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
- <argument index="1" name="anchor_mode" type="int">
+ <argument index="1" name="anchor" type="float">
</argument>
<argument index="2" name="offset" type="float">
</argument>
+ <argument index="3" name="push_opposite_anchor" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_anchors_preset">
+ <return type="void">
+ </return>
+ <argument index="0" name="preset" type="int" enum="Control.LayoutPreset">
+ </argument>
+ <argument index="1" name="keep_margin" type="bool" default="false">
+ </argument>
<description>
- Change the anchor (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) type for a margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM), and also set its offset. This is a helper (see [method set_anchor] and [method set_margin]).
</description>
</method>
<method name="set_area_as_parent_rect">
+ <return type="void">
+ </return>
<argument index="0" name="margin" type="int" default="0">
</argument>
<description>
@@ -11831,6 +13445,8 @@
</description>
</method>
<method name="set_begin">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
@@ -11838,37 +13454,49 @@
</description>
</method>
<method name="set_clip_contents">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_custom_minimum_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_default_cursor_shape">
- <argument index="0" name="shape" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="shape" type="int" enum="Control.CursorShape">
</argument>
<description>
Set the default cursor shape for this control. See enum CURSOR_* for the list of shapes.
</description>
</method>
<method name="set_drag_forwarding">
+ <return type="void">
+ </return>
<argument index="0" name="target" type="Control">
</argument>
<description>
</description>
</method>
<method name="set_drag_preview">
+ <return type="void">
+ </return>
<argument index="0" name="control" type="Control">
</argument>
<description>
</description>
</method>
<method name="set_end">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
@@ -11876,14 +13504,18 @@
</description>
</method>
<method name="set_focus_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Control.FocusMode">
</argument>
<description>
Set the focus access mode for the control (FOCUS_NONE, FOCUS_CLICK, FOCUS_ALL). Only one Control can be focused at the same time, and it will receive keyboard signals.
</description>
</method>
<method name="set_focus_neighbour">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="neighbour" type="NodePath">
</argument>
@@ -11892,6 +13524,8 @@
</description>
</method>
<method name="set_global_position">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
@@ -11899,12 +13533,16 @@
</description>
</method>
<method name="set_h_grow_direction">
- <argument index="0" name="direction" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="direction" type="int" enum="Control.GrowDirection">
</argument>
<description>
</description>
</method>
<method name="set_h_size_flags">
+ <return type="void">
+ </return>
<argument index="0" name="flags" type="int">
</argument>
<description>
@@ -11912,7 +13550,9 @@
</description>
</method>
<method name="set_margin">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="offset" type="float">
</argument>
@@ -11921,19 +13561,25 @@
</description>
</method>
<method name="set_mouse_filter">
- <argument index="0" name="filter" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="filter" type="int" enum="Control.MouseFilter">
</argument>
<description>
Set when the control is ignoring mouse events (even touchpad events send mouse events). (see the MOUSE_FILTER_* constants)
</description>
</method>
<method name="set_pivot_offset">
+ <return type="void">
+ </return>
<argument index="0" name="pivot_offset" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_position">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
@@ -11941,6 +13587,8 @@
</description>
</method>
<method name="set_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
@@ -11948,6 +13596,8 @@
</description>
</method>
<method name="set_rotation_deg">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
@@ -11955,12 +13605,16 @@
</description>
</method>
<method name="set_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
@@ -11968,6 +13622,8 @@
</description>
</method>
<method name="set_stretch_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="ratio" type="float">
</argument>
<description>
@@ -11975,6 +13631,8 @@
</description>
</method>
<method name="set_theme">
+ <return type="void">
+ </return>
<argument index="0" name="theme" type="Theme">
</argument>
<description>
@@ -11982,6 +13640,8 @@
</description>
</method>
<method name="set_tooltip">
+ <return type="void">
+ </return>
<argument index="0" name="tooltip" type="String">
</argument>
<description>
@@ -11989,12 +13649,16 @@
</description>
</method>
<method name="set_v_grow_direction">
- <argument index="0" name="direction" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="direction" type="int" enum="Control.GrowDirection">
</argument>
<description>
</description>
</method>
<method name="set_v_size_flags">
+ <return type="void">
+ </return>
<argument index="0" name="flags" type="int">
</argument>
<description>
@@ -12002,6 +13666,8 @@
</description>
</method>
<method name="show_modal">
+ <return type="void">
+ </return>
<argument index="0" name="exclusive" type="bool" default="false">
</argument>
<description>
@@ -12009,6 +13675,8 @@
</description>
</method>
<method name="warp_mouse">
+ <return type="void">
+ </return>
<argument index="0" name="to_pos" type="Vector2">
</argument>
<description>
@@ -12016,13 +13684,13 @@
</method>
</methods>
<members>
- <member name="anchor_bottom" type="int" setter="_set_anchor" getter="get_anchor" brief="">
+ <member name="anchor_bottom" type="float" setter="_set_anchor" getter="get_anchor" brief="">
</member>
- <member name="anchor_left" type="int" setter="_set_anchor" getter="get_anchor" brief="">
+ <member name="anchor_left" type="float" setter="_set_anchor" getter="get_anchor" brief="">
</member>
- <member name="anchor_right" type="int" setter="_set_anchor" getter="get_anchor" brief="">
+ <member name="anchor_right" type="float" setter="_set_anchor" getter="get_anchor" brief="">
</member>
- <member name="anchor_top" type="int" setter="_set_anchor" getter="get_anchor" brief="">
+ <member name="anchor_top" type="float" setter="_set_anchor" getter="get_anchor" brief="">
</member>
<member name="focus_neighbour_bottom" type="NodePath" setter="set_focus_neighbour" getter="get_focus_neighbour" brief="">
</member>
@@ -12032,21 +13700,21 @@
</member>
<member name="focus_neighbour_top" type="NodePath" setter="set_focus_neighbour" getter="get_focus_neighbour" brief="">
</member>
- <member name="grow_horizontal" type="int" setter="set_h_grow_direction" getter="get_h_grow_direction" brief="">
+ <member name="grow_horizontal" type="int" setter="set_h_grow_direction" getter="get_h_grow_direction" brief="" enum="Control.GrowDirection">
</member>
- <member name="grow_vertical" type="int" setter="set_v_grow_direction" getter="get_v_grow_direction" brief="">
+ <member name="grow_vertical" type="int" setter="set_v_grow_direction" getter="get_v_grow_direction" brief="" enum="Control.GrowDirection">
</member>
<member name="hint_tooltip" type="String" setter="set_tooltip" getter="_get_tooltip" brief="">
</member>
- <member name="margin_bottom" type="int" setter="set_margin" getter="get_margin" brief="">
+ <member name="margin_bottom" type="float" setter="set_margin" getter="get_margin" brief="">
</member>
- <member name="margin_left" type="int" setter="set_margin" getter="get_margin" brief="">
+ <member name="margin_left" type="float" setter="set_margin" getter="get_margin" brief="">
</member>
- <member name="margin_right" type="int" setter="set_margin" getter="get_margin" brief="">
+ <member name="margin_right" type="float" setter="set_margin" getter="get_margin" brief="">
</member>
- <member name="margin_top" type="int" setter="set_margin" getter="get_margin" brief="">
+ <member name="margin_top" type="float" setter="set_margin" getter="get_margin" brief="">
</member>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" brief="">
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" brief="" enum="Control.MouseFilter">
</member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" brief="">
</member>
@@ -12064,7 +13732,7 @@
</member>
<member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" brief="">
</member>
- <member name="size_flags_stretch_ratio" type="int" setter="set_stretch_ratio" getter="get_stretch_ratio" brief="">
+ <member name="size_flags_stretch_ratio" type="float" setter="set_stretch_ratio" getter="get_stretch_ratio" brief="">
</member>
<member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" brief="">
</member>
@@ -12119,14 +13787,6 @@
</signal>
</signals>
<constants>
- <constant name="ANCHOR_BEGIN" value="0">
- X is relative to MARGIN_LEFT, Y is relative to MARGIN_TOP.
- </constant>
- <constant name="ANCHOR_END" value="1">
- X is relative to -MARGIN_RIGHT, Y is relative to -MARGIN_BOTTOM.
- </constant>
- <constant name="ANCHOR_CENTER" value="2">
- </constant>
<constant name="FOCUS_NONE" value="0">
Control can't acquire focus.
</constant>
@@ -12136,25 +13796,25 @@
<constant name="FOCUS_ALL" value="2">
Control can acquire focus if clicked, or by pressing TAB/Directionals in the keyboard from another Control.
</constant>
- <constant name="NOTIFICATION_RESIZED" value="40">
+ <constant name="NOTIFICATION_RESIZED" value="40" enum="">
Control changed size (get_size() reports the new size).
</constant>
- <constant name="NOTIFICATION_MOUSE_ENTER" value="41">
+ <constant name="NOTIFICATION_MOUSE_ENTER" value="41" enum="">
Mouse pointer entered the area of the Control.
</constant>
- <constant name="NOTIFICATION_MOUSE_EXIT" value="42">
+ <constant name="NOTIFICATION_MOUSE_EXIT" value="42" enum="">
Mouse pointer exited the area of the Control.
</constant>
- <constant name="NOTIFICATION_FOCUS_ENTER" value="43">
+ <constant name="NOTIFICATION_FOCUS_ENTER" value="43" enum="">
Control gained focus.
</constant>
- <constant name="NOTIFICATION_FOCUS_EXIT" value="44">
+ <constant name="NOTIFICATION_FOCUS_EXIT" value="44" enum="">
Control lost focus.
</constant>
- <constant name="NOTIFICATION_THEME_CHANGED" value="45">
+ <constant name="NOTIFICATION_THEME_CHANGED" value="45" enum="">
Theme changed. Redrawing is desired.
</constant>
- <constant name="NOTIFICATION_MODAL_CLOSE" value="46">
+ <constant name="NOTIFICATION_MODAL_CLOSE" value="46" enum="">
Modal control was closed.
</constant>
<constant name="CURSOR_ARROW" value="0">
@@ -12191,6 +13851,38 @@
</constant>
<constant name="CURSOR_HELP" value="16">
</constant>
+ <constant name="PRESET_TOP_LEFT" value="0">
+ </constant>
+ <constant name="PRESET_TOP_RIGHT" value="1">
+ </constant>
+ <constant name="PRESET_BOTTOM_LEFT" value="2">
+ </constant>
+ <constant name="PRESET_BOTTOM_RIGHT" value="3">
+ </constant>
+ <constant name="PRESET_CENTER_LEFT" value="4">
+ </constant>
+ <constant name="PRESET_CENTER_TOP" value="5">
+ </constant>
+ <constant name="PRESET_CENTER_RIGHT" value="6">
+ </constant>
+ <constant name="PRESET_CENTER_BOTTOM" value="7">
+ </constant>
+ <constant name="PRESET_CENTER" value="8">
+ </constant>
+ <constant name="PRESET_LEFT_WIDE" value="9">
+ </constant>
+ <constant name="PRESET_TOP_WIDE" value="10">
+ </constant>
+ <constant name="PRESET_RIGHT_WIDE" value="11">
+ </constant>
+ <constant name="PRESET_BOTTOM_WIDE" value="12">
+ </constant>
+ <constant name="PRESET_VCENTER_WIDE" value="13">
+ </constant>
+ <constant name="PRESET_HCENTER_WIDE" value="14">
+ </constant>
+ <constant name="PRESET_WIDE" value="15">
+ </constant>
<constant name="SIZE_EXPAND" value="2">
</constant>
<constant name="SIZE_FILL" value="1">
@@ -12211,6 +13903,12 @@
</constant>
<constant name="GROW_DIRECTION_END" value="1">
</constant>
+ <constant name="ANCHOR_BEGIN" value="0">
+ X is relative to MARGIN_LEFT, Y is relative to MARGIN_TOP.
+ </constant>
+ <constant name="ANCHOR_END" value="1">
+ X is relative to -MARGIN_RIGHT, Y is relative to -MARGIN_BOTTOM.
+ </constant>
</constants>
</class>
<class name="ConvexPolygonShape" inherits="Shape" category="Core">
@@ -12228,6 +13926,8 @@
</description>
</method>
<method name="set_points">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector3Array">
</argument>
<description>
@@ -12235,7 +13935,7 @@
</method>
</methods>
<members>
- <member name="points" type="Array" setter="set_points" getter="get_points" brief="">
+ <member name="points" type="PoolVector3Array" setter="set_points" getter="get_points" brief="">
</member>
</members>
<constants>
@@ -12258,6 +13958,8 @@
</description>
</method>
<method name="set_point_cloud">
+ <return type="void">
+ </return>
<argument index="0" name="point_cloud" type="PoolVector2Array">
</argument>
<description>
@@ -12265,6 +13967,8 @@
</description>
</method>
<method name="set_points">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<description>
@@ -12304,15 +14008,15 @@
</description>
</method>
<method name="get_side" qualifiers="const">
- <return type="Object">
+ <return type="Image">
</return>
- <argument index="0" name="side" type="int">
+ <argument index="0" name="side" type="int" enum="CubeMap.Side">
</argument>
<description>
</description>
</method>
<method name="get_storage" qualifiers="const">
- <return type="int">
+ <return type="int" enum="CubeMap.Storage">
</return>
<description>
</description>
@@ -12324,27 +14028,35 @@
</description>
</method>
<method name="set_flags">
+ <return type="void">
+ </return>
<argument index="0" name="flags" type="int">
</argument>
<description>
</description>
</method>
<method name="set_lossy_storage_quality">
+ <return type="void">
+ </return>
<argument index="0" name="quality" type="float">
</argument>
<description>
</description>
</method>
<method name="set_side">
- <argument index="0" name="side" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="side" type="int" enum="CubeMap.Side">
</argument>
- <argument index="1" name="image" type="Object">
+ <argument index="1" name="image" type="Image">
</argument>
<description>
</description>
</method>
<method name="set_storage">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="CubeMap.Storage">
</argument>
<description>
</description>
@@ -12410,24 +14122,32 @@
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_depth">
+ <return type="void">
+ </return>
<argument index="0" name="divisions" type="int">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_height">
+ <return type="void">
+ </return>
<argument index="0" name="divisions" type="int">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_width">
+ <return type="void">
+ </return>
<argument index="0" name="subdivide" type="int">
</argument>
<description>
@@ -12435,7 +14155,7 @@
</method>
</methods>
<members>
- <member name="size" type="Vector2" setter="set_size" getter="get_size" brief="">
+ <member name="size" type="Vector3" setter="set_size" getter="get_size" brief="">
</member>
<member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief="">
</member>
@@ -12462,22 +14182,28 @@
</argument>
<argument index="2" name="right_tangent" type="float" default="0">
</argument>
- <argument index="3" name="left_mode" type="int" default="0">
+ <argument index="3" name="left_mode" type="int" enum="Curve.TangentMode" default="0">
</argument>
- <argument index="4" name="right_mode" type="int" default="0">
+ <argument index="4" name="right_mode" type="int" enum="Curve.TangentMode" default="0">
</argument>
<description>
</description>
</method>
<method name="bake">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="clean_dupes">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="clear_points">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -12500,7 +14226,7 @@
</description>
</method>
<method name="get_point_left_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Curve.TangentMode">
</return>
<argument index="0" name="index" type="int">
</argument>
@@ -12524,7 +14250,7 @@
</description>
</method>
<method name="get_point_right_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Curve.TangentMode">
</return>
<argument index="0" name="index" type="int">
</argument>
@@ -12556,38 +14282,50 @@
</description>
</method>
<method name="remove_point">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<description>
</description>
</method>
<method name="set_bake_resolution">
+ <return type="void">
+ </return>
<argument index="0" name="resolution" type="int">
</argument>
<description>
</description>
</method>
<method name="set_max_value">
+ <return type="void">
+ </return>
<argument index="0" name="max" type="float">
</argument>
<description>
</description>
</method>
<method name="set_min_value">
+ <return type="void">
+ </return>
<argument index="0" name="min" type="float">
</argument>
<description>
</description>
</method>
<method name="set_point_left_mode">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Curve.TangentMode">
</argument>
<description>
</description>
</method>
<method name="set_point_left_tangent">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<argument index="1" name="tangent" type="float">
@@ -12596,6 +14334,8 @@
</description>
</method>
<method name="set_point_offset">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<argument index="1" name="offset" type="float">
@@ -12604,14 +14344,18 @@
</description>
</method>
<method name="set_point_right_mode">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Curve.TangentMode">
</argument>
<description>
</description>
</method>
<method name="set_point_right_tangent">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<argument index="1" name="tangent" type="float">
@@ -12620,6 +14364,8 @@
</description>
</method>
<method name="set_point_value">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<argument index="1" name="y" type="float">
@@ -12629,7 +14375,7 @@
</method>
</methods>
<members>
- <member name="_data" type="int" setter="_set_data" getter="_get_data" brief="">
+ <member name="_data" type="Array" setter="_set_data" getter="_get_data" brief="">
</member>
<member name="bake_resolution" type="int" setter="set_bake_resolution" getter="get_bake_resolution" brief="">
</member>
@@ -12657,11 +14403,13 @@
</description>
<methods>
<method name="add_point">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
- <argument index="1" name="in" type="Vector2" default="Vector2(0, 0)">
+ <argument index="1" name="in" type="Vector2" default="Vector2( 0, 0 )">
</argument>
- <argument index="2" name="out" type="Vector2" default="Vector2(0, 0)">
+ <argument index="2" name="out" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<argument index="3" name="atpos" type="int" default="-1">
</argument>
@@ -12671,6 +14419,8 @@
</description>
</method>
<method name="clear_points">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -12764,6 +14514,8 @@
</description>
</method>
<method name="remove_point">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -12771,6 +14523,8 @@
</description>
</method>
<method name="set_bake_interval">
+ <return type="void">
+ </return>
<argument index="0" name="distance" type="float">
</argument>
<description>
@@ -12778,6 +14532,8 @@
</description>
</method>
<method name="set_point_in">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="pos" type="Vector2">
@@ -12787,6 +14543,8 @@
</description>
</method>
<method name="set_point_out">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="pos" type="Vector2">
@@ -12796,6 +14554,8 @@
</description>
</method>
<method name="set_point_pos">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="pos" type="Vector2">
@@ -12804,7 +14564,7 @@
Sets the position for the vertex "idx". If the index is out of bounds, the function sends an error to the console.
</description>
</method>
- <method name="tesselate" qualifiers="const">
+ <method name="tessellate" qualifiers="const">
<return type="PoolVector2Array">
</return>
<argument index="0" name="max_stages" type="int" default="5">
@@ -12820,7 +14580,7 @@
</method>
</methods>
<members>
- <member name="_data" type="int" setter="_set_data" getter="_get_data" brief="">
+ <member name="_data" type="Dictionary" setter="_set_data" getter="_get_data" brief="">
</member>
<member name="bake_interval" type="float" setter="set_bake_interval" getter="get_bake_interval" brief="">
</member>
@@ -12838,11 +14598,13 @@
</description>
<methods>
<method name="add_point">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector3">
</argument>
- <argument index="1" name="in" type="Vector3" default="Vector3(0, 0, 0)">
+ <argument index="1" name="in" type="Vector3" default="Vector3( 0, 0, 0 )">
</argument>
- <argument index="2" name="out" type="Vector3" default="Vector3(0, 0, 0)">
+ <argument index="2" name="out" type="Vector3" default="Vector3( 0, 0, 0 )">
</argument>
<argument index="3" name="atpos" type="int" default="-1">
</argument>
@@ -12852,6 +14614,8 @@
</description>
</method>
<method name="clear_points">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -12961,6 +14725,8 @@
</description>
</method>
<method name="remove_point">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -12968,6 +14734,8 @@
</description>
</method>
<method name="set_bake_interval">
+ <return type="void">
+ </return>
<argument index="0" name="distance" type="float">
</argument>
<description>
@@ -12975,6 +14743,8 @@
</description>
</method>
<method name="set_point_in">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="pos" type="Vector3">
@@ -12984,6 +14754,8 @@
</description>
</method>
<method name="set_point_out">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="pos" type="Vector3">
@@ -12993,6 +14765,8 @@
</description>
</method>
<method name="set_point_pos">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="pos" type="Vector3">
@@ -13002,6 +14776,8 @@
</description>
</method>
<method name="set_point_tilt">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="tilt" type="float">
@@ -13011,7 +14787,7 @@
The tilt controls the rotation along the look-at axis an object traveling the path would have. In the case of a curve controlling a [PathFollow], this tilt is an offset over the natural tilt the PathFollow calculates.
</description>
</method>
- <method name="tesselate" qualifiers="const">
+ <method name="tessellate" qualifiers="const">
<return type="PoolVector3Array">
</return>
<argument index="0" name="max_stages" type="int" default="5">
@@ -13027,7 +14803,7 @@
</method>
</methods>
<members>
- <member name="_data" type="int" setter="_set_data" getter="_get_data" brief="">
+ <member name="_data" type="Dictionary" setter="_set_data" getter="_get_data" brief="">
</member>
<member name="bake_interval" type="float" setter="set_bake_interval" getter="get_bake_interval" brief="">
</member>
@@ -13048,12 +14824,16 @@
</description>
</method>
<method name="set_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="Curve">
</argument>
<description>
</description>
</method>
<method name="set_width">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<description>
@@ -13106,30 +14886,40 @@
</description>
</method>
<method name="set_bottom_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
<method name="set_height">
+ <return type="void">
+ </return>
<argument index="0" name="height" type="float">
</argument>
<description>
</description>
</method>
<method name="set_radial_segments">
+ <return type="void">
+ </return>
<argument index="0" name="segments" type="int">
</argument>
<description>
</description>
</method>
<method name="set_rings">
+ <return type="void">
+ </return>
<argument index="0" name="rings" type="int">
</argument>
<description>
</description>
</method>
<method name="set_top_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
@@ -13188,6 +14978,8 @@
</description>
</method>
<method name="set_damping">
+ <return type="void">
+ </return>
<argument index="0" name="damping" type="float">
</argument>
<description>
@@ -13195,6 +14987,8 @@
</description>
</method>
<method name="set_length">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
@@ -13202,6 +14996,8 @@
</description>
</method>
<method name="set_rest_length">
+ <return type="void">
+ </return>
<argument index="0" name="rest_length" type="float">
</argument>
<description>
@@ -13209,6 +15005,8 @@
</description>
</method>
<method name="set_stiffness">
+ <return type="void">
+ </return>
<argument index="0" name="stiffness" type="float">
</argument>
<description>
@@ -13315,7 +15113,7 @@
</description>
<methods>
<method name="get_shadow_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="DirectionalLight.ShadowMode">
</return>
<description>
</description>
@@ -13327,22 +15125,28 @@
</description>
</method>
<method name="set_blend_splits">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_shadow_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="DirectionalLight.ShadowMode">
</argument>
<description>
</description>
</method>
</methods>
<members>
+ <member name="directional_shadow_bias_split_scale" type="float" setter="set_param" getter="get_param" brief="">
+ </member>
<member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled" brief="">
</member>
- <member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" brief="">
+ <member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" brief="" enum="DirectionalLight.ShadowMode">
</member>
<member name="directional_shadow_normal_bias" type="float" setter="set_param" getter="get_param" brief="">
</member>
@@ -13387,7 +15191,7 @@
</description>
<methods>
<method name="change_dir">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="todir" type="String">
</argument>
@@ -13397,7 +15201,7 @@
</description>
</method>
<method name="copy">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="from" type="String">
</argument>
@@ -13478,7 +15282,7 @@
</description>
</method>
<method name="list_dir_begin">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="skip_navigational" type="bool" default="false">
</argument>
@@ -13491,12 +15295,14 @@
</description>
</method>
<method name="list_dir_end">
+ <return type="void">
+ </return>
<description>
Close the current stream opened with [method list_dir_begin] (whether it has been fully processed with [method get_next] or not does not matter).
</description>
</method>
<method name="make_dir">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -13506,7 +15312,7 @@
</description>
</method>
<method name="make_dir_recursive">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -13516,7 +15322,7 @@
</description>
</method>
<method name="open">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -13526,7 +15332,7 @@
</description>
</method>
<method name="remove">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -13536,7 +15342,7 @@
</description>
</method>
<method name="rename">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="from" type="String">
</argument>
@@ -13558,6 +15364,8 @@
</description>
<methods>
<method name="add_fallback">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="DynamicFontData">
</argument>
<description>
@@ -13610,12 +15418,16 @@
</description>
</method>
<method name="remove_fallback">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
</description>
</method>
<method name="set_fallback">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="data" type="DynamicFontData">
@@ -13624,18 +15436,24 @@
</description>
</method>
<method name="set_font_data">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="DynamicFontData">
</argument>
<description>
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="int">
</argument>
<description>
</description>
</method>
<method name="set_spacing">
+ <return type="void">
+ </return>
<argument index="0" name="type" type="int">
</argument>
<argument index="1" name="value" type="int">
@@ -13644,12 +15462,16 @@
</description>
</method>
<method name="set_use_filter">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_use_mipmaps">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -13698,6 +15520,8 @@
</description>
</method>
<method name="set_font_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -13718,17 +15542,21 @@
</description>
<methods>
<method name="add_filter">
+ <return type="void">
+ </return>
<argument index="0" name="filter" type="String">
</argument>
<description>
</description>
</method>
<method name="clear_filters">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="get_access" qualifiers="const">
- <return type="int">
+ <return type="int" enum="EditorFileDialog.Access">
</return>
<description>
</description>
@@ -13752,13 +15580,13 @@
</description>
</method>
<method name="get_display_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="EditorFileDialog.DisplayMode">
</return>
<description>
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="EditorFileDialog.Mode">
</return>
<description>
</description>
@@ -13770,6 +15598,8 @@
</description>
</method>
<method name="invalidate">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -13786,48 +15616,64 @@
</description>
</method>
<method name="set_access">
- <argument index="0" name="access" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="access" type="int" enum="EditorFileDialog.Access">
</argument>
<description>
</description>
</method>
<method name="set_current_dir">
+ <return type="void">
+ </return>
<argument index="0" name="dir" type="String">
</argument>
<description>
</description>
</method>
<method name="set_current_file">
+ <return type="void">
+ </return>
<argument index="0" name="file" type="String">
</argument>
<description>
</description>
</method>
<method name="set_current_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
</description>
</method>
<method name="set_disable_overwrite_warning">
+ <return type="void">
+ </return>
<argument index="0" name="disable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_display_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="EditorFileDialog.DisplayMode">
</argument>
<description>
</description>
</method>
<method name="set_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="EditorFileDialog.Mode">
</argument>
<description>
</description>
</method>
<method name="set_show_hidden_files">
+ <return type="void">
+ </return>
<argument index="0" name="show" type="bool">
</argument>
<description>
@@ -13920,16 +15766,22 @@
</description>
</method>
<method name="scan">
+ <return type="void">
+ </return>
<description>
Scan the filesystem for changes.
</description>
</method>
<method name="scan_sources">
+ <return type="void">
+ </return>
<description>
Check if the source of any imported resource changed.
</description>
</method>
<method name="update_file">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -13943,6 +15795,12 @@
Emitted if the filesystem changed.
</description>
</signal>
+ <signal name="resources_reimported">
+ <argument index="0" name="resources" type="PoolStringArray">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="sources_changed">
<argument index="0" name="exist" type="bool">
</argument>
@@ -13991,6 +15849,14 @@
<description>
</description>
</method>
+ <method name="get_file_import_is_valid" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_file_path" qualifiers="const">
<return type="String">
</return>
@@ -14026,7 +15892,7 @@
</description>
</method>
<method name="get_subdir">
- <return type="Object">
+ <return type="EditorFileSystemDirectory">
</return>
<argument index="0" name="idx" type="int">
</argument>
@@ -14131,6 +15997,130 @@
<constants>
</constants>
</class>
+<class name="EditorInterface" inherits="Node" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="edit_resource">
+ <return type="void">
+ </return>
+ <argument index="0" name="resource" type="Resource">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_base_control">
+ <return type="Control">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_edited_scene_root">
+ <return type="Node">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_editor_settings">
+ <return type="EditorSettings">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_editor_viewport">
+ <return type="Control">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_open_scenes" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_resource_filesystem">
+ <return type="EditorFileSystem">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_resource_previewer">
+ <return type="EditorResourcePreview">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_script_editor">
+ <return type="ScriptEditor">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_selection">
+ <return type="EditorSelection">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="inspect_object">
+ <return type="void">
+ </return>
+ <argument index="0" name="object" type="Object">
+ </argument>
+ <argument index="1" name="for_property" type="String" default="&quot;&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="make_mesh_previews">
+ <return type="Array">
+ </return>
+ <argument index="0" name="arg0" type="Array">
+ </argument>
+ <argument index="1" name="arg1" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="open_scene_from_path">
+ <return type="void">
+ </return>
+ <argument index="0" name="scene_filepath" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="reload_scene_from_path">
+ <return type="void">
+ </return>
+ <argument index="0" name="scene_filepath" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="save_scene">
+ <return type="int" enum="Error">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="save_scene_as">
+ <return type="void">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <argument index="1" name="with_preview" type="bool" default="true">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="EditorPlugin" inherits="Node" category="Core">
<brief_description>
Used by the editor to extend its functionality.
@@ -14151,7 +16141,9 @@
</description>
</method>
<method name="add_control_to_container">
- <argument index="0" name="container" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="container" type="int" enum="EditorPlugin.CustomControlContainer">
</argument>
<argument index="1" name="control" type="Control">
</argument>
@@ -14162,7 +16154,9 @@
</description>
</method>
<method name="add_control_to_dock">
- <argument index="0" name="slot" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="slot" type="int" enum="EditorPlugin.DockSlot">
</argument>
<argument index="1" name="control" type="Control">
</argument>
@@ -14173,6 +16167,8 @@
</description>
</method>
<method name="add_custom_type">
+ <return type="void">
+ </return>
<argument index="0" name="type" type="String">
</argument>
<argument index="1" name="base" type="String">
@@ -14189,26 +16185,34 @@
</description>
</method>
<method name="add_import_plugin">
- <argument index="0" name="arg0" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="importer" type="EditorImportPlugin">
</argument>
<description>
</description>
</method>
<method name="add_tool_submenu_item">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="submenu" type="PopupMenu">
+ <argument index="1" name="submenu" type="Object">
</argument>
<description>
</description>
</method>
<method name="apply_changes" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
This method is called when the editor is about to save the project, switch to another tab, etc. It asks the plugin to apply any pending state changes to ensure consistency.
This is used, for example, in shader editors to let the plugin know that it must apply the shader code being written by the user to the object.
</description>
</method>
<method name="clear" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
Clear all the state and reset the object being edited to zero. This ensures your plugin does not keep editing a currently existing node, or a node from the wrong scene.
</description>
@@ -14223,18 +16227,14 @@
</description>
</method>
<method name="edit" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="object" type="Object">
</argument>
<description>
This function is used for plugins that edit specific object types (nodes or resources). It requests the editor to edit the given object.
</description>
</method>
- <method name="edit_resource">
- <argument index="0" name="arg0" type="Object">
- </argument>
- <description>
- </description>
- </method>
<method name="forward_canvas_gui_input" qualifiers="virtual">
<return type="bool">
</return>
@@ -14246,6 +16246,8 @@
</description>
</method>
<method name="forward_draw_over_canvas" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="canvas_xform" type="Transform2D">
</argument>
<argument index="1" name="canvas" type="Control">
@@ -14266,13 +16268,6 @@
If you would like to always gets those input events then additionally use [method set_input_forwarding_always_enabled].
</description>
</method>
- <method name="get_base_control">
- <return type="Control">
- </return>
- <description>
- Get a base control where it's safe to place dialogs. Many plugins open dialogs and they need a control as a base to make sure they use the editor icons and theme.
- </description>
- </method>
<method name="get_breakpoints" qualifiers="virtual">
<return type="PoolStringArray">
</return>
@@ -14280,67 +16275,16 @@
This is for editors that edit script based objects. You can return a list of breakpoints in the format (script:line), for example: res://path_to_script.gd:25
</description>
</method>
- <method name="get_editor_settings">
- <return type="EditorSettings">
+ <method name="get_editor_interface">
+ <return type="EditorInterface">
</return>
<description>
- Get the general settings for the editor (the same window that appears in the Settings menu).
</description>
</method>
- <method name="get_edited_scene_root">
- <return type="Node">
- </return>
- <description>
- Returns root node of currently edited scene.
- </description>
- </method>
- <method name="get_editor_viewport">
- <return type="Control">
- </return>
- <description>
- Get the main editor control. Use this as a parent for main screens.
- </description>
- </method>
- <method name="get_name" qualifiers="virtual">
+ <method name="get_plugin_name" qualifiers="virtual">
<return type="String">
</return>
<description>
- Get the name of the editor plugin. For main scren plugins this is what will appear in the selector (which by default is 2D, 3D, Script).
- </description>
- </method>
- <method name="get_open_scenes">
- <return type="Array">
- </return>
- <description>
- Will return an Array of Strings which represent file paths to currently open scenes.
- </description>
- </method>
- <method name="get_resource_filesystem">
- <return type="EditorFileSystem">
- </return>
- <description>
- Get the filesystem cache for all resources in the project.
- </description>
- </method>
- <method name="get_resource_previewer">
- <return type="EditorResourcePreview">
- </return>
- <description>
- Get tool for generating resource previews.
- </description>
- </method>
- <method name="get_script_editor">
- <return type="ScriptEditor">
- </return>
- <description>
- Will return ScriptEditor object which contains informations about state of the scripts which are currently open by the editor.
- </description>
- </method>
- <method name="get_selection">
- <return type="EditorSelection">
- </return>
- <description>
- Get the object that handles the selection of nodes in the Scene Tree editor.
</description>
</method>
<method name="get_state" qualifiers="virtual">
@@ -14358,6 +16302,8 @@
</description>
</method>
<method name="get_window_layout" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="layout" type="ConfigFile">
</argument>
<description>
@@ -14381,25 +16327,22 @@
</description>
</method>
<method name="hide_bottom_panel">
+ <return type="void">
+ </return>
<description>
</description>
</method>
- <method name="inspect_object">
- <argument index="0" name="object" type="Object">
- </argument>
- <argument index="1" name="for_property" type="String" default="&quot;&quot;">
- </argument>
- <description>
- Inspect an object in the inspector.
- </description>
- </method>
<method name="make_bottom_panel_item_visible">
+ <return type="void">
+ </return>
<argument index="0" name="item" type="Control">
</argument>
<description>
</description>
</method>
<method name="make_visible" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="visible" type="bool">
</argument>
<description>
@@ -14407,26 +16350,16 @@
Remember that you have to manage the visibility of all your editor controls manually.
</description>
</method>
- <method name="open_scene_from_path">
- <argument index="0" name="scene_filepath" type="String">
- </argument>
- <description>
- Opens scene in editor. Do not use during plugin initialization. If you need, then use it together with [method Object.call_deferred].
- </description>
- </method>
<method name="queue_save_layout" qualifiers="const">
+ <return type="void">
+ </return>
<description>
Queue save the project's editor layout.
</description>
</method>
- <method name="reload_scene_from_path">
- <argument index="0" name="scene_filepath" type="String">
- </argument>
- <description>
- Reloads already loaded editor scene.
- </description>
- </method>
<method name="remove_control_from_bottom_panel">
+ <return type="void">
+ </return>
<argument index="0" name="control" type="Control">
</argument>
<description>
@@ -14434,6 +16367,8 @@
</description>
</method>
<method name="remove_control_from_docks">
+ <return type="void">
+ </return>
<argument index="0" name="control" type="Control">
</argument>
<description>
@@ -14441,6 +16376,8 @@
</description>
</method>
<method name="remove_custom_type">
+ <return type="void">
+ </return>
<argument index="0" name="type" type="String">
</argument>
<description>
@@ -14448,22 +16385,30 @@
</description>
</method>
<method name="remove_import_plugin">
- <argument index="0" name="arg0" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="importer" type="EditorImportPlugin">
</argument>
<description>
</description>
</method>
<method name="save_external_data" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
This method is called after the editor saves the project or when it's closed. It asks the plugin to save edited external scenes/resources.
</description>
</method>
<method name="set_input_event_forwarding_always_enabled">
+ <return type="void">
+ </return>
<description>
Use this method if you always want to receive inputs from 3D view screen inside [method forward_spatial_gui_input]. It might be especially usable if your plugin will want to use raycast in the scene.
</description>
</method>
<method name="set_state" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="state" type="Dictionary">
</argument>
<description>
@@ -14471,6 +16416,8 @@
</description>
</method>
<method name="set_window_layout" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="layout" type="ConfigFile">
</argument>
<description>
@@ -14478,11 +16425,36 @@
</description>
</method>
<method name="update_canvas">
+ <return type="void">
+ </return>
<description>
Updates the control used to draw the edited scene over the 2D canvas. This is used together with [method forward_canvas_input_event].
</description>
</method>
</methods>
+ <signals>
+ <signal name="main_screen_changed">
+ <argument index="0" name="screen_name" type="String">
+ </argument>
+ <description>
+ Emitted when user change main screen view (2D, 3D, Script, AssetLib). Works also with screens which are defined by plugins.
+ </description>
+ </signal>
+ <signal name="scene_changed">
+ <argument index="0" name="scene_root" type="Object">
+ </argument>
+ <description>
+ Emitted when user change scene. The argument is a root node of freshly opened scene.
+ </description>
+ </signal>
+ <signal name="scene_closed">
+ <argument index="0" name="filepath" type="String">
+ </argument>
+ <description>
+ Emitted when user close scene. The argument is file path to a closed scene.
+ </description>
+ </signal>
+ </signals>
<constants>
<constant name="CONTAINER_TOOLBAR" value="0">
</constant>
@@ -14517,29 +16489,6 @@
<constant name="DOCK_SLOT_MAX" value="8">
</constant>
</constants>
- <signals>
- <signal name="main_screen_changed">
- <argument index="0" name="screen_name" type="String">
- </argument>
- <description>
- Emitted when user change main screen view (2D, 3D, Script, AssetLib). Works also with screens which are defined by plugins.
- </description>
- </signal>
- <signal name="scene_changed">
- <argument index="0" name="scene_root" type="Node">
- </argument>
- <description>
- Emitted when user change scene. The argument is a root node of freshly opened scene.
- </description>
- </signal>
- <signal name="scene_closed">
- <argument index="0" name="filepath" type="String">
- </argument>
- <description>
- Emitted when user close scene. The argument is file path to a closed scene.
- </description>
- </signal>
- </signals>
</class>
<class name="EditorResourcePreview" inherits="Node" category="Core">
<brief_description>
@@ -14550,6 +16499,8 @@
</description>
<methods>
<method name="add_preview_generator">
+ <return type="void">
+ </return>
<argument index="0" name="generator" type="EditorResourcePreviewGenerator">
</argument>
<description>
@@ -14557,6 +16508,8 @@
</description>
</method>
<method name="check_for_invalidation">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -14564,6 +16517,8 @@
</description>
</method>
<method name="queue_edited_resource_preview">
+ <return type="void">
+ </return>
<argument index="0" name="resource" type="Resource">
</argument>
<argument index="1" name="receiver" type="Object">
@@ -14577,6 +16532,8 @@
</description>
</method>
<method name="queue_resource_preview">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<argument index="1" name="receiver" type="Object">
@@ -14590,6 +16547,8 @@
</description>
</method>
<method name="remove_preview_generator">
+ <return type="void">
+ </return>
<argument index="0" name="generator" type="EditorResourcePreviewGenerator">
</argument>
<description>
@@ -14661,17 +16620,27 @@
</description>
<methods>
<method name="_run" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="add_root_node">
- <argument index="0" name="node" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="node" type="Node">
</argument>
<description>
</description>
</method>
+ <method name="get_editor_interface">
+ <return type="EditorInterface">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_scene">
- <return type="Object">
+ <return type="Node">
</return>
<description>
</description>
@@ -14689,6 +16658,8 @@
</description>
<methods>
<method name="add_node">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Node">
</argument>
<description>
@@ -14696,6 +16667,8 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear the selection.
</description>
@@ -14715,6 +16688,8 @@
</description>
</method>
<method name="remove_node">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Node">
</argument>
<description>
@@ -14747,6 +16722,8 @@
</description>
<methods>
<method name="add_property_info">
+ <return type="void">
+ </return>
<argument index="0" name="info" type="Dictionary">
</argument>
<description>
@@ -14767,6 +16744,8 @@
</description>
</method>
<method name="erase">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<description>
@@ -14784,7 +16763,7 @@
<return type="String">
</return>
<description>
- Get the specific project settings path. Projects all have an unique sub-directory inside the settings path where project specific settings are saved.
+ Get the specific project settings path. Projects all have a unique sub-directory inside the settings path where project specific settings are saved.
</description>
</method>
<method name="get_recent_dirs" qualifiers="const">
@@ -14804,6 +16783,8 @@
</description>
</method>
<method name="set_favorite_dirs">
+ <return type="void">
+ </return>
<argument index="0" name="dirs" type="PoolStringArray">
</argument>
<description>
@@ -14811,6 +16792,8 @@
</description>
</method>
<method name="set_recent_dirs">
+ <return type="void">
+ </return>
<argument index="0" name="dirs" type="PoolStringArray">
</argument>
<description>
@@ -14836,12 +16819,16 @@
</description>
<methods>
<method name="add_collision_segments">
+ <return type="void">
+ </return>
<argument index="0" name="segments" type="PoolVector3Array">
</argument>
<description>
</description>
</method>
<method name="add_collision_triangles">
+ <return type="void">
+ </return>
<argument index="0" name="triangles" type="TriangleMesh">
</argument>
<description>
@@ -14849,6 +16836,8 @@
</description>
</method>
<method name="add_handles">
+ <return type="void">
+ </return>
<argument index="0" name="handles" type="PoolVector3Array">
</argument>
<argument index="1" name="billboard" type="bool" default="false">
@@ -14861,6 +16850,8 @@
</description>
</method>
<method name="add_lines">
+ <return type="void">
+ </return>
<argument index="0" name="lines" type="PoolVector3Array">
</argument>
<argument index="1" name="material" type="Material">
@@ -14872,17 +16863,20 @@
</description>
</method>
<method name="add_mesh">
- <argument index="0" name="mesh" type="Mesh">
+ <return type="void">
+ </return>
+ <argument index="0" name="mesh" type="ArrayMesh">
</argument>
<argument index="1" name="billboard" type="bool" default="false">
</argument>
- <argument index="2" name="skeleton" type="RID" default="[RID]">
+ <argument index="2" name="skeleton" type="RID">
</argument>
<description>
- Add a mesh to the gizmo, this is used for visualization. Call this function during [method redraw].
</description>
</method>
<method name="add_unscaled_billboard">
+ <return type="void">
+ </return>
<argument index="0" name="material" type="Material">
</argument>
<argument index="1" name="default_scale" type="float" default="1">
@@ -14892,15 +16886,19 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="commit_handle" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<argument index="1" name="restore" type="Variant">
</argument>
- <argument index="2" name="cancel" type="bool">
+ <argument index="2" name="cancel" type="bool" default="false">
</argument>
<description>
Commit a handle being edited (handles must have been prevously added by [method add_handles]).
@@ -14927,11 +16925,15 @@
</description>
</method>
<method name="redraw" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
This function is called when the Spatial this gizmo refers to changes (the [method Spatial.update_gizmo] is called).
</description>
</method>
<method name="set_handle" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<argument index="1" name="camera" type="Camera">
@@ -14944,10 +16946,35 @@
</description>
</method>
<method name="set_spatial_node">
- <argument index="0" name="node" type="Spatial">
+ <return type="void">
+ </return>
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
+<class name="EncodedObjectAsID" inherits="Reference" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_object_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_object_id">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
</argument>
<description>
- Call this function once and upon creation of the gizmo, otherwise no other function will work. The argument is the node being edited by the gizmo.
</description>
</method>
</methods>
@@ -15014,13 +17041,29 @@
"string" - major + minor + patch + status + revision in a single String
</description>
</method>
+ <method name="is_editor_hint" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_in_fixed_frame" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
+ <method name="set_editor_hint">
+ <return type="void">
+ </return>
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_iterations_per_second">
+ <return type="void">
+ </return>
<argument index="0" name="iterations_per_second" type="int">
</argument>
<description>
@@ -15028,12 +17071,16 @@
</description>
</method>
<method name="set_target_fps">
+ <return type="void">
+ </return>
<argument index="0" name="target_fps" type="int">
</argument>
<description>
</description>
</method>
<method name="set_time_scale">
+ <return type="void">
+ </return>
<argument index="0" name="time_scale" type="float">
</argument>
<description>
@@ -15056,7 +17103,7 @@
</description>
</method>
<method name="get_adjustment_color_correction" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
@@ -15092,7 +17139,7 @@
</description>
</method>
<method name="get_background" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Environment.BGMode">
</return>
<description>
</description>
@@ -15128,7 +17175,7 @@
</description>
</method>
<method name="get_dof_blur_far_quality" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Environment.DOFBlurQuality">
</return>
<description>
</description>
@@ -15152,7 +17199,7 @@
</description>
</method>
<method name="get_dof_blur_near_quality" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Environment.DOFBlurQuality">
</return>
<description>
</description>
@@ -15218,7 +17265,7 @@
</description>
</method>
<method name="get_glow_blend_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Environment.GlowBlendMode">
</return>
<description>
</description>
@@ -15254,7 +17301,7 @@
</description>
</method>
<method name="get_sky" qualifiers="const">
- <return type="CubeMap">
+ <return type="Sky">
</return>
<description>
</description>
@@ -15374,7 +17421,7 @@
</description>
</method>
<method name="get_tonemapper" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Environment.ToneMapper">
</return>
<description>
</description>
@@ -15466,258 +17513,344 @@
</description>
</method>
<method name="set_adjustment_brightness">
+ <return type="void">
+ </return>
<argument index="0" name="brightness" type="float">
</argument>
<description>
</description>
</method>
<method name="set_adjustment_color_correction">
- <argument index="0" name="color_correction" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="color_correction" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_adjustment_contrast">
+ <return type="void">
+ </return>
<argument index="0" name="contrast" type="float">
</argument>
<description>
</description>
</method>
<method name="set_adjustment_enable">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_adjustment_saturation">
+ <return type="void">
+ </return>
<argument index="0" name="saturation" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ambient_light_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_ambient_light_energy">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ambient_light_sky_contribution">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_background">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Environment.BGMode">
</argument>
<description>
</description>
</method>
<method name="set_bg_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_bg_energy">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_canvas_max_layer">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_far_amount">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_far_distance">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_far_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_far_quality">
- <argument index="0" name="intensity" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="intensity" type="int" enum="Environment.DOFBlurQuality">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_far_transition">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_near_amount">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_near_distance">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_near_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_near_quality">
- <argument index="0" name="level" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="level" type="int" enum="Environment.DOFBlurQuality">
</argument>
<description>
</description>
</method>
<method name="set_dof_blur_near_transition">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_fog_depth_begin">
+ <return type="void">
+ </return>
<argument index="0" name="distance" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_depth_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_depth_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_fog_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_fog_height_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_height_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_fog_height_max">
+ <return type="void">
+ </return>
<argument index="0" name="height" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_height_min">
+ <return type="void">
+ </return>
<argument index="0" name="height" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_sun_amount">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_sun_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_fog_transmit_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fog_transmit_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_glow_bicubic_upscale">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_glow_blend_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Environment.GlowBlendMode">
</argument>
<description>
</description>
</method>
<method name="set_glow_bloom">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_glow_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_glow_hdr_bleed_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="float">
</argument>
<description>
</description>
</method>
<method name="set_glow_hdr_bleed_threshold">
+ <return type="void">
+ </return>
<argument index="0" name="threshold" type="float">
</argument>
<description>
</description>
</method>
<method name="set_glow_intensity">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_glow_level">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="enabled" type="bool">
@@ -15726,157 +17859,209 @@
</description>
</method>
<method name="set_glow_strength">
+ <return type="void">
+ </return>
<argument index="0" name="strength" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sky">
+ <return type="void">
+ </return>
<argument index="0" name="sky" type="Sky">
</argument>
<description>
</description>
</method>
<method name="set_sky_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssao_bias">
+ <return type="void">
+ </return>
<argument index="0" name="bias" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssao_blur">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_ssao_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_ssao_direct_light_affect">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssao_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_ssao_intensity">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssao_intensity2">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssao_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssao_radius2">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssr_depth_tolerance">
+ <return type="void">
+ </return>
<argument index="0" name="depth_tolerance" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssr_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_ssr_fade_in">
+ <return type="void">
+ </return>
<argument index="0" name="fade_in" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssr_fade_out">
+ <return type="void">
+ </return>
<argument index="0" name="fade_out" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ssr_max_steps">
+ <return type="void">
+ </return>
<argument index="0" name="max_steps" type="int">
</argument>
<description>
</description>
</method>
<method name="set_ssr_rough">
+ <return type="void">
+ </return>
<argument index="0" name="rough" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_tonemap_auto_exposure">
+ <return type="void">
+ </return>
<argument index="0" name="auto_exposure" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_tonemap_auto_exposure_grey">
+ <return type="void">
+ </return>
<argument index="0" name="exposure_grey" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tonemap_auto_exposure_max">
+ <return type="void">
+ </return>
<argument index="0" name="exposure_max" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tonemap_auto_exposure_min">
+ <return type="void">
+ </return>
<argument index="0" name="exposure_min" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tonemap_auto_exposure_speed">
+ <return type="void">
+ </return>
<argument index="0" name="exposure_speed" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tonemap_exposure">
+ <return type="void">
+ </return>
<argument index="0" name="exposure" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tonemap_white">
+ <return type="void">
+ </return>
<argument index="0" name="white" type="float">
</argument>
<description>
</description>
</method>
<method name="set_tonemapper">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Environment.ToneMapper">
</argument>
<description>
</description>
@@ -15915,7 +18100,7 @@
</member>
<member name="background_energy" type="float" setter="set_bg_energy" getter="get_bg_energy" brief="">
</member>
- <member name="background_mode" type="int" setter="set_background" getter="get_background" brief="">
+ <member name="background_mode" type="int" setter="set_background" getter="get_background" brief="" enum="Environment.BGMode">
</member>
<member name="background_sky" type="Sky" setter="set_sky" getter="get_sky" brief="">
</member>
@@ -15927,7 +18112,7 @@
</member>
<member name="dof_blur_far_enabled" type="bool" setter="set_dof_blur_far_enabled" getter="is_dof_blur_far_enabled" brief="">
</member>
- <member name="dof_blur_far_quality" type="int" setter="set_dof_blur_far_quality" getter="get_dof_blur_far_quality" brief="">
+ <member name="dof_blur_far_quality" type="int" setter="set_dof_blur_far_quality" getter="get_dof_blur_far_quality" brief="" enum="Environment.DOFBlurQuality">
</member>
<member name="dof_blur_far_transition" type="float" setter="set_dof_blur_far_transition" getter="get_dof_blur_far_transition" brief="">
</member>
@@ -15937,7 +18122,7 @@
</member>
<member name="dof_blur_near_enabled" type="bool" setter="set_dof_blur_near_enabled" getter="is_dof_blur_near_enabled" brief="">
</member>
- <member name="dof_blur_near_quality" type="int" setter="set_dof_blur_near_quality" getter="get_dof_blur_near_quality" brief="">
+ <member name="dof_blur_near_quality" type="int" setter="set_dof_blur_near_quality" getter="get_dof_blur_near_quality" brief="" enum="Environment.DOFBlurQuality">
</member>
<member name="dof_blur_near_transition" type="float" setter="set_dof_blur_near_transition" getter="get_dof_blur_near_transition" brief="">
</member>
@@ -15969,7 +18154,7 @@
</member>
<member name="glow_bicubic_upscale" type="bool" setter="set_glow_bicubic_upscale" getter="is_glow_bicubic_upscale_enabled" brief="">
</member>
- <member name="glow_blend_mode" type="int" setter="set_glow_blend_mode" getter="get_glow_blend_mode" brief="">
+ <member name="glow_blend_mode" type="int" setter="set_glow_blend_mode" getter="get_glow_blend_mode" brief="" enum="Environment.GlowBlendMode">
</member>
<member name="glow_bloom" type="float" setter="set_glow_bloom" getter="get_glow_bloom" brief="">
</member>
@@ -16029,7 +18214,7 @@
</member>
<member name="tonemap_exposure" type="float" setter="set_tonemap_exposure" getter="get_tonemap_exposure" brief="">
</member>
- <member name="tonemap_mode" type="int" setter="set_tonemapper" getter="get_tonemapper" brief="">
+ <member name="tonemap_mode" type="int" setter="set_tonemapper" getter="get_tonemapper" brief="" enum="Environment.ToneMapper">
</member>
<member name="tonemap_white" type="float" setter="set_tonemap_white" getter="get_tonemap_white" brief="">
</member>
@@ -16095,6 +18280,8 @@
</description>
<methods>
<method name="close">
+ <return type="void">
+ </return>
<description>
Close the currently opened file.
</description>
@@ -16183,7 +18370,7 @@
</description>
</method>
<method name="get_error" qualifiers="const">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<description>
Get the last error that happened when trying to perform operations. Compare with the [code]ERR_FILE_*[/code] constants from [@Global Scope].
@@ -16258,6 +18445,8 @@
</description>
</method>
<method name="get_var" qualifiers="const">
+ <return type="Variant">
+ </return>
<description>
Get the next Variant value from the file.
</description>
@@ -16270,7 +18459,7 @@
</description>
</method>
<method name="open">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -16281,7 +18470,7 @@
</description>
</method>
<method name="open_compressed">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -16294,7 +18483,7 @@
</description>
</method>
<method name="open_encrypted">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -16307,7 +18496,7 @@
</description>
</method>
<method name="open_encrypted_with_pass">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -16320,6 +18509,8 @@
</description>
</method>
<method name="seek">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="int">
</argument>
<description>
@@ -16327,6 +18518,8 @@
</description>
</method>
<method name="seek_end">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="int" default="0">
</argument>
<description>
@@ -16334,6 +18527,8 @@
</description>
</method>
<method name="set_endian_swap">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -16342,6 +18537,8 @@
</description>
</method>
<method name="store_16">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="int">
</argument>
<description>
@@ -16349,6 +18546,8 @@
</description>
</method>
<method name="store_32">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="int">
</argument>
<description>
@@ -16356,6 +18555,8 @@
</description>
</method>
<method name="store_64">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="int">
</argument>
<description>
@@ -16363,6 +18564,8 @@
</description>
</method>
<method name="store_8">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="int">
</argument>
<description>
@@ -16370,6 +18573,8 @@
</description>
</method>
<method name="store_buffer">
+ <return type="void">
+ </return>
<argument index="0" name="buffer" type="PoolByteArray">
</argument>
<description>
@@ -16377,6 +18582,8 @@
</description>
</method>
<method name="store_double">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="float">
</argument>
<description>
@@ -16384,6 +18591,8 @@
</description>
</method>
<method name="store_float">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="float">
</argument>
<description>
@@ -16391,6 +18600,8 @@
</description>
</method>
<method name="store_line">
+ <return type="void">
+ </return>
<argument index="0" name="line" type="String">
</argument>
<description>
@@ -16398,6 +18609,8 @@
</description>
</method>
<method name="store_pascal_string">
+ <return type="void">
+ </return>
<argument index="0" name="string" type="String">
</argument>
<description>
@@ -16405,6 +18618,8 @@
</description>
</method>
<method name="store_real">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="float">
</argument>
<description>
@@ -16412,6 +18627,8 @@
</description>
</method>
<method name="store_string">
+ <return type="void">
+ </return>
<argument index="0" name="string" type="String">
</argument>
<description>
@@ -16419,6 +18636,8 @@
</description>
</method>
<method name="store_var">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="Variant">
</argument>
<description>
@@ -16461,6 +18680,8 @@
</description>
<methods>
<method name="add_filter">
+ <return type="void">
+ </return>
<argument index="0" name="filter" type="String">
</argument>
<description>
@@ -16468,12 +18689,14 @@
</description>
</method>
<method name="clear_filters">
+ <return type="void">
+ </return>
<description>
Clear all the added filters in the dialog.
</description>
</method>
<method name="get_access" qualifiers="const">
- <return type="int">
+ <return type="int" enum="FileDialog.Access">
</return>
<description>
Return the file access permission of the dialog.
@@ -16507,7 +18730,7 @@
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="FileDialog.Mode">
</return>
<description>
Get the file dialog mode from the MODE_* enum.
@@ -16521,6 +18744,8 @@
</description>
</method>
<method name="invalidate">
+ <return type="void">
+ </return>
<description>
Invalidate and update the current dialog content list.
</description>
@@ -16533,13 +18758,17 @@
</description>
</method>
<method name="set_access">
- <argument index="0" name="access" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="access" type="int" enum="FileDialog.Access">
</argument>
<description>
Set the file access permission of the dialog(Must be one of [ACCESS_RESOURCES], [ACCESS_USERDATA] or [ACCESS_FILESYSTEM]).
</description>
</method>
<method name="set_current_dir">
+ <return type="void">
+ </return>
<argument index="0" name="dir" type="String">
</argument>
<description>
@@ -16547,6 +18776,8 @@
</description>
</method>
<method name="set_current_file">
+ <return type="void">
+ </return>
<argument index="0" name="file" type="String">
</argument>
<description>
@@ -16554,6 +18785,8 @@
</description>
</method>
<method name="set_current_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -16561,19 +18794,25 @@
</description>
</method>
<method name="set_filters">
+ <return type="void">
+ </return>
<argument index="0" name="filters" type="PoolStringArray">
</argument>
<description>
</description>
</method>
<method name="set_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="FileDialog.Mode">
</argument>
<description>
Set the file dialog mode from the MODE_* enum.
</description>
</method>
<method name="set_show_hidden_files">
+ <return type="void">
+ </return>
<argument index="0" name="show" type="bool">
</argument>
<description>
@@ -16582,11 +18821,11 @@
</method>
</methods>
<members>
- <member name="access" type="int" setter="set_access" getter="get_access" brief="">
+ <member name="access" type="int" setter="set_access" getter="get_access" brief="" enum="FileDialog.Access">
</member>
<member name="filters" type="PoolStringArray" setter="set_filters" getter="get_filters" brief="">
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="FileDialog.Mode">
</member>
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files" brief="">
</member>
@@ -16654,17 +18893,19 @@
Internationalized font and text drawing support.
</brief_description>
<description>
- Font contains an unicode compatible character set, as well as the ability to draw it with variable width, ascent, descent and kerning. For creating fonts from TTF files (or other font formats), see the editor support for fonts. TODO check wikipedia for graph of ascent/baseline/descent/height/etc.
+ Font contains a unicode compatible character set, as well as the ability to draw it with variable width, ascent, descent and kerning. For creating fonts from TTF files (or other font formats), see the editor support for fonts. TODO check wikipedia for graph of ascent/baseline/descent/height/etc.
</description>
<methods>
<method name="draw" qualifiers="const">
+ <return type="void">
+ </return>
<argument index="0" name="canvas_item" type="RID">
</argument>
<argument index="1" name="pos" type="Vector2">
</argument>
<argument index="2" name="string" type="String">
</argument>
- <argument index="3" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="4" name="clip_w" type="int" default="-1">
</argument>
@@ -16683,7 +18924,7 @@
</argument>
<argument index="3" name="next" type="int" default="-1">
</argument>
- <argument index="4" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="4" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<description>
Draw character "char" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally kerning if "next" is passed. clipping the width. "pos" specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. The width used by the character is returned, making this function useful for drawing strings character by character.
@@ -16726,6 +18967,8 @@
</description>
</method>
<method name="update_changes">
+ <return type="void">
+ </return>
<description>
After editing a font (changing size, ascent, char rects, etc.). Call this function to propagate changes to controls that might use it.
</description>
@@ -16750,6 +18993,8 @@
</description>
</method>
<method name="set_function">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -16757,6 +19002,8 @@
</description>
</method>
<method name="set_instance">
+ <return type="void">
+ </return>
<argument index="0" name="instance" type="Object">
</argument>
<description>
@@ -16788,7 +19035,7 @@
<method name="resume">
<return type="Variant">
</return>
- <argument index="0" name="arg" type="Variant" default="NULL">
+ <argument index="0" name="arg" type="Variant" default="null">
</argument>
<description>
Resume execution of the yielded function call.
@@ -16808,39 +19055,67 @@
<constants>
</constants>
</class>
-<class name="GDNativeClass" inherits="Reference" category="Core">
+<class name="GDNative" inherits="Reference" category="Core">
<brief_description>
</brief_description>
<description>
</description>
<methods>
- <method name="new">
+ <method name="call_native">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="procedure_name" type="String">
+ </argument>
+ <argument index="1" name="arguments" type="String">
+ </argument>
+ <argument index="2" name="arg2" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_library">
+ <return type="GDNativeLibrary">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="initialize">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_library">
+ <return type="void">
+ </return>
+ <argument index="0" name="library" type="GDNativeLibrary">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="terminate">
+ <return type="bool">
+ </return>
<description>
</description>
</method>
</methods>
+ <members>
+ <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library" brief="">
+ </member>
+ </members>
<constants>
</constants>
</class>
-<class name="GDNativeLibrary" inherits="Resource" category="Core">
+<class name="GDNativeClass" inherits="Reference" category="Core">
<brief_description>
</brief_description>
<description>
</description>
<methods>
- <method name="get_platform_file" qualifiers="const">
- <return type="String">
+ <method name="new">
+ <return type="Variant">
</return>
- <argument index="0" name="platform" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_platform_file">
- <argument index="0" name="platform" type="String">
- </argument>
- <argument index="1" name="file" type="String">
- </argument>
<description>
</description>
</method>
@@ -16848,49 +19123,31 @@
<constants>
</constants>
</class>
-<class name="GDNativeScript" inherits="Script" category="Core">
+<class name="GDNativeLibrary" inherits="Resource" category="Core">
<brief_description>
</brief_description>
<description>
</description>
<methods>
- <method name="get_library" qualifiers="const">
- <return type="Object">
- </return>
- <description>
- </description>
- </method>
- <method name="get_script_name" qualifiers="const">
+ <method name="get_library_path" qualifiers="const">
<return type="String">
</return>
+ <argument index="0" name="platform" type="String">
+ </argument>
<description>
</description>
</method>
- <method name="new" qualifiers="vararg">
- <return type="Object">
+ <method name="set_library_path">
+ <return type="void">
</return>
- <description>
- </description>
- </method>
- <method name="set_library">
- <argument index="0" name="library" type="Object">
+ <argument index="0" name="platform" type="String">
</argument>
- <description>
- </description>
- </method>
- <method name="set_script_name">
- <argument index="0" name="script_name" type="String">
+ <argument index="1" name="path" type="String">
</argument>
<description>
</description>
</method>
</methods>
- <members>
- <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library" brief="">
- </member>
- <member name="script_name" type="String" setter="set_script_name" getter="get_script_name" brief="">
- </member>
- </members>
<constants>
</constants>
</class>
@@ -16923,7 +19180,9 @@
</description>
<methods>
<method name="bake">
- <argument index="0" name="from_node" type="Object" default="NULL">
+ <return type="void">
+ </return>
+ <argument index="0" name="from_node" type="Node" default="null">
</argument>
<argument index="1" name="create_visual_debug" type="bool" default="false">
</argument>
@@ -16931,6 +19190,8 @@
</description>
</method>
<method name="debug_bake">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -16965,7 +19226,7 @@
</description>
</method>
<method name="get_probe_data" qualifiers="const">
- <return type="Object">
+ <return type="GIProbeData">
</return>
<description>
</description>
@@ -16977,7 +19238,7 @@
</description>
</method>
<method name="get_subdiv" qualifiers="const">
- <return type="int">
+ <return type="int" enum="GIProbe.Subdiv">
</return>
<description>
</description>
@@ -16995,61 +19256,81 @@
</description>
</method>
<method name="set_bias">
+ <return type="void">
+ </return>
<argument index="0" name="max" type="float">
</argument>
<description>
</description>
</method>
<method name="set_compress">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_dynamic_range">
+ <return type="void">
+ </return>
<argument index="0" name="max" type="int">
</argument>
<description>
</description>
</method>
<method name="set_energy">
+ <return type="void">
+ </return>
<argument index="0" name="max" type="float">
</argument>
<description>
</description>
</method>
<method name="set_extents">
+ <return type="void">
+ </return>
<argument index="0" name="extents" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_interior">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_normal_bias">
+ <return type="void">
+ </return>
<argument index="0" name="max" type="float">
</argument>
<description>
</description>
</method>
<method name="set_probe_data">
- <argument index="0" name="data" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="data" type="GIProbeData">
</argument>
<description>
</description>
</method>
<method name="set_propagation">
+ <return type="void">
+ </return>
<argument index="0" name="max" type="float">
</argument>
<description>
</description>
</method>
<method name="set_subdiv">
- <argument index="0" name="subdiv" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="subdiv" type="int" enum="GIProbe.Subdiv">
</argument>
<description>
</description>
@@ -17074,7 +19355,7 @@
</member>
<member name="propagation" type="float" setter="set_propagation" getter="get_propagation" brief="">
</member>
- <member name="subdiv" type="int" setter="set_subdiv" getter="get_subdiv" brief="">
+ <member name="subdiv" type="int" setter="set_subdiv" getter="get_subdiv" brief="" enum="GIProbe.Subdiv">
</member>
</members>
<constants>
@@ -17161,66 +19442,88 @@
</description>
</method>
<method name="set_bias">
+ <return type="void">
+ </return>
<argument index="0" name="bias" type="float">
</argument>
<description>
</description>
</method>
<method name="set_bounds">
+ <return type="void">
+ </return>
<argument index="0" name="bounds" type="Rect3">
</argument>
<description>
</description>
</method>
<method name="set_cell_size">
+ <return type="void">
+ </return>
<argument index="0" name="cell_size" type="float">
</argument>
<description>
</description>
</method>
<method name="set_compress">
+ <return type="void">
+ </return>
<argument index="0" name="compress" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_dynamic_data">
+ <return type="void">
+ </return>
<argument index="0" name="dynamic_data" type="PoolIntArray">
</argument>
<description>
</description>
</method>
<method name="set_dynamic_range">
+ <return type="void">
+ </return>
<argument index="0" name="dynamic_range" type="int">
</argument>
<description>
</description>
</method>
<method name="set_energy">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_interior">
+ <return type="void">
+ </return>
<argument index="0" name="interior" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_normal_bias">
+ <return type="void">
+ </return>
<argument index="0" name="bias" type="float">
</argument>
<description>
</description>
</method>
<method name="set_propagation">
+ <return type="void">
+ </return>
<argument index="0" name="propagation" type="float">
</argument>
<description>
</description>
</method>
<method name="set_to_cell_xform">
+ <return type="void">
+ </return>
<argument index="0" name="to_cell_xform" type="Transform">
</argument>
<description>
@@ -17263,7 +19566,7 @@
<method name="get_flag_x" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="flag" type="int">
+ <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag">
</argument>
<description>
</description>
@@ -17271,7 +19574,7 @@
<method name="get_flag_y" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="flag" type="int">
+ <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag">
</argument>
<description>
</description>
@@ -17279,7 +19582,7 @@
<method name="get_flag_z" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="flag" type="int">
+ <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag">
</argument>
<description>
</description>
@@ -17287,7 +19590,7 @@
<method name="get_param_x" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param">
</argument>
<description>
</description>
@@ -17295,7 +19598,7 @@
<method name="get_param_y" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param">
</argument>
<description>
</description>
@@ -17303,13 +19606,15 @@
<method name="get_param_z" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param">
</argument>
<description>
</description>
</method>
<method name="set_flag_x">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag">
</argument>
<argument index="1" name="value" type="bool">
</argument>
@@ -17317,7 +19622,9 @@
</description>
</method>
<method name="set_flag_y">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag">
</argument>
<argument index="1" name="value" type="bool">
</argument>
@@ -17325,7 +19632,9 @@
</description>
</method>
<method name="set_flag_z">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag">
</argument>
<argument index="1" name="value" type="bool">
</argument>
@@ -17333,7 +19642,9 @@
</description>
</method>
<method name="set_param_x">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -17341,7 +19652,9 @@
</description>
</method>
<method name="set_param_y">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -17349,7 +19662,9 @@
</description>
</method>
<method name="set_param_z">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -17527,7 +19842,7 @@
</argument>
<argument index="3" name="lats" type="int">
</argument>
- <argument index="4" name="axis" type="int" default="2">
+ <argument index="4" name="axis" type="int" enum="Vector3.Axis" default="2">
</argument>
<description>
</description>
@@ -17541,7 +19856,7 @@
</argument>
<argument index="2" name="sides" type="int">
</argument>
- <argument index="3" name="axis" type="int" default="2">
+ <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="2">
</argument>
<description>
</description>
@@ -17653,6 +19968,8 @@
</description>
</method>
<method name="ray_intersects_triangle">
+ <return type="Variant">
+ </return>
<argument index="0" name="from" type="Vector3">
</argument>
<argument index="1" name="dir" type="Vector3">
@@ -17707,6 +20024,8 @@
</description>
</method>
<method name="segment_intersects_segment_2d">
+ <return type="Variant">
+ </return>
<argument index="0" name="from_a" type="Vector2">
</argument>
<argument index="1" name="to_a" type="Vector2">
@@ -17733,6 +20052,8 @@
</description>
</method>
<method name="segment_intersects_triangle">
+ <return type="Variant">
+ </return>
<argument index="0" name="from" type="Vector3">
</argument>
<argument index="1" name="to" type="Vector3">
@@ -17767,7 +20088,7 @@
</description>
<methods>
<method name="get_cast_shadows_setting" qualifiers="const">
- <return type="int">
+ <return type="int" enum="GeometryInstance.ShadowCastingSetting">
</return>
<description>
</description>
@@ -17781,7 +20102,7 @@
<method name="get_flag" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="flag" type="int">
+ <argument index="0" name="flag" type="int" enum="GeometryInstance.Flags">
</argument>
<description>
</description>
@@ -17811,26 +20132,32 @@
</description>
</method>
<method name="get_material_override" qualifiers="const">
- <return type="Object">
+ <return type="Material">
</return>
<description>
Return the material override for the whole geometry.
</description>
</method>
<method name="set_cast_shadows_setting">
- <argument index="0" name="shadow_casting_setting" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="shadow_casting_setting" type="int" enum="GeometryInstance.ShadowCastingSetting">
</argument>
<description>
</description>
</method>
<method name="set_extra_cull_margin">
+ <return type="void">
+ </return>
<argument index="0" name="margin" type="float">
</argument>
<description>
</description>
</method>
<method name="set_flag">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="GeometryInstance.Flags">
</argument>
<argument index="1" name="value" type="bool">
</argument>
@@ -17838,31 +20165,41 @@
</description>
</method>
<method name="set_lod_max_distance">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="float">
</argument>
<description>
</description>
</method>
<method name="set_lod_max_hysteresis">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="float">
</argument>
<description>
</description>
</method>
<method name="set_lod_min_distance">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="float">
</argument>
<description>
</description>
</method>
<method name="set_lod_min_hysteresis">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="float">
</argument>
<description>
</description>
</method>
<method name="set_material_override">
- <argument index="0" name="material" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="material" type="Material">
</argument>
<description>
Set the material override for the whole geometry.
@@ -17870,188 +20207,36 @@
</method>
</methods>
<members>
- <member name="cast_shadow" type="int" setter="set_cast_shadows_setting" getter="get_cast_shadows_setting" brief="">
+ <member name="cast_shadow" type="int" setter="set_cast_shadows_setting" getter="get_cast_shadows_setting" brief="" enum="GeometryInstance.ShadowCastingSetting">
</member>
<member name="extra_cull_margin" type="float" setter="set_extra_cull_margin" getter="get_extra_cull_margin" brief="">
</member>
- <member name="lod_max_distance" type="int" setter="set_lod_max_distance" getter="get_lod_max_distance" brief="">
+ <member name="lod_max_distance" type="float" setter="set_lod_max_distance" getter="get_lod_max_distance" brief="">
</member>
- <member name="lod_max_hysteresis" type="int" setter="set_lod_max_hysteresis" getter="get_lod_max_hysteresis" brief="">
+ <member name="lod_max_hysteresis" type="float" setter="set_lod_max_hysteresis" getter="get_lod_max_hysteresis" brief="">
</member>
- <member name="lod_min_distance" type="int" setter="set_lod_min_distance" getter="get_lod_min_distance" brief="">
+ <member name="lod_min_distance" type="float" setter="set_lod_min_distance" getter="get_lod_min_distance" brief="">
</member>
- <member name="lod_min_hysteresis" type="int" setter="set_lod_min_hysteresis" getter="get_lod_min_hysteresis" brief="">
+ <member name="lod_min_hysteresis" type="float" setter="set_lod_min_hysteresis" getter="get_lod_min_hysteresis" brief="">
</member>
- <member name="material_override" type="ShaderMaterial,SpatialMaterial" setter="set_material_override" getter="get_material_override" brief="">
+ <member name="material_override" type="Material" setter="set_material_override" getter="get_material_override" brief="">
</member>
<member name="use_in_baked_light" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
- <member name="visible_in_all_rooms" type="bool" setter="set_flag" getter="get_flag" brief="">
- </member>
</members>
<constants>
- <constant name="FLAG_CAST_SHADOW" value="0">
- </constant>
- <constant name="FLAG_VISIBLE_IN_ALL_ROOMS" value="1">
- </constant>
- <constant name="FLAG_MAX" value="3">
+ <constant name="FLAG_MAX" value="1" enum="">
</constant>
- <constant name="SHADOW_CASTING_SETTING_OFF" value="0">
+ <constant name="SHADOW_CASTING_SETTING_OFF" value="0" enum="">
</constant>
- <constant name="SHADOW_CASTING_SETTING_ON" value="1">
+ <constant name="SHADOW_CASTING_SETTING_ON" value="1" enum="">
</constant>
- <constant name="SHADOW_CASTING_SETTING_DOUBLE_SIDED" value="2">
+ <constant name="SHADOW_CASTING_SETTING_DOUBLE_SIDED" value="2" enum="">
</constant>
- <constant name="SHADOW_CASTING_SETTING_SHADOWS_ONLY" value="3">
+ <constant name="SHADOW_CASTING_SETTING_SHADOWS_ONLY" value="3" enum="">
</constant>
</constants>
</class>
-<class name="ProjectSettings" inherits="Object" category="Core">
- <brief_description>
- Contains global variables accessible from everywhere.
- </brief_description>
- <description>
- Contains global variables accessible from everywhere. Use the normal [Object] API, such as "ProjectSettings.get(variable)", "ProjectSettings.set(variable,value)" or "ProjectSettings.has(variable)" to access them. Variables stored in project.godot are also loaded into ProjectSettings, making this object very useful for reading custom game configuration options.
- </description>
- <methods>
- <method name="add_property_info">
- <argument index="0" name="hint" type="Dictionary">
- </argument>
- <description>
- Add a custom property info to a property. The dictionary must contain: name:[String](the name of the property) and type:[int](see TYPE_* in [@Global Scope]), and optionally hint:[int](see PROPERTY_HINT_* in [@Global Scope]), hint_string:[String].
- Example:
- [codeblock]
- ProjectSettings.set("category/property_name", 0)
-
- var property_info = {
- "name": "category/property_name",
- "type": TYPE_INT,
- "hint": PROPERTY_HINT_ENUM,
- "hint_string": "one,two,three"
- }
-
- ProjectSettings.add_property_info(property_info)
- [/codeblock]
- </description>
- </method>
- <method name="clear">
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- Clear the whole configuration (not recommended, may break things).
- </description>
- </method>
- <method name="get_order" qualifiers="const">
- <return type="int">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- Return the order of a configuration value (influences when saved to the config file).
- </description>
- </method>
- <method name="get_singleton" qualifiers="const">
- <return type="Object">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="globalize_path" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="path" type="String">
- </argument>
- <description>
- Convert a localized path (res://) to a full native OS path.
- </description>
- </method>
- <method name="has" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- Return true if a configuration value is present.
- </description>
- </method>
- <method name="has_singleton" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="load_resource_pack">
- <return type="bool">
- </return>
- <argument index="0" name="pack" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="localize_path" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="path" type="String">
- </argument>
- <description>
- Convert a path to a localized path (res:// path).
- </description>
- </method>
- <method name="property_can_revert">
- <return type="bool">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="property_get_revert">
- <return type="Variant">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="save">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="save_custom">
- <return type="int">
- </return>
- <argument index="0" name="file" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_initial_value">
- <argument index="0" name="name" type="String">
- </argument>
- <argument index="1" name="value" type="Variant">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_order">
- <argument index="0" name="name" type="String">
- </argument>
- <argument index="1" name="pos" type="int">
- </argument>
- <description>
- Set the order of a configuration value (influences when saved to the config file).
- </description>
- </method>
- </methods>
- <constants>
- </constants>
-</class>
<class name="Gradient" inherits="Resource" category="Core">
<brief_description>
Color interpolator node
@@ -18061,6 +20246,8 @@
</description>
<methods>
<method name="add_point">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="float">
</argument>
<argument index="1" name="color" type="Color">
@@ -18118,6 +20305,8 @@
</description>
</method>
<method name="remove_point">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="int">
</argument>
<description>
@@ -18125,6 +20314,8 @@
</description>
</method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="point" type="int">
</argument>
<argument index="1" name="color" type="Color">
@@ -18134,6 +20325,8 @@
</description>
</method>
<method name="set_colors">
+ <return type="void">
+ </return>
<argument index="0" name="colors" type="PoolColorArray">
</argument>
<description>
@@ -18141,6 +20334,8 @@
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="point" type="int">
</argument>
<argument index="1" name="offset" type="float">
@@ -18150,6 +20345,8 @@
</description>
</method>
<method name="set_offsets">
+ <return type="void">
+ </return>
<argument index="0" name="offsets" type="PoolRealArray">
</argument>
<description>
@@ -18158,9 +20355,9 @@
</method>
</methods>
<members>
- <member name="colors" type="float" setter="set_colors" getter="get_colors" brief="">
+ <member name="colors" type="PoolColorArray" setter="set_colors" getter="get_colors" brief="">
</member>
- <member name="offsets" type="float" setter="set_offsets" getter="get_offsets" brief="">
+ <member name="offsets" type="PoolRealArray" setter="set_offsets" getter="get_offsets" brief="">
</member>
</members>
<constants>
@@ -18179,12 +20376,16 @@
</description>
</method>
<method name="set_gradient">
+ <return type="void">
+ </return>
<argument index="0" name="gradient" type="Gradient">
</argument>
<description>
</description>
</method>
<method name="set_width">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<description>
@@ -18205,12 +20406,12 @@
GraphEdit is an area capable of showing various GraphNodes. It manages connection events between them.
</brief_description>
<description>
- GraphEdit manages the showing of GraphNodes it contains, as well as connections an disconnections between them. Signals are sent for each of these two events. Disconnection between GraphNodes slots is disabled by default.
+ GraphEdit manages the showing of GraphNodes it contains, as well as connections and disconnections between them. Signals are sent for each of these two events. Disconnection between GraphNodes slots is disabled by default.
It is greatly advised to enable low processor usage mode (see [method OS.set_low_processor_usage_mode]) when using GraphEdits.
</description>
<methods>
<method name="connect_node">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="from" type="String">
</argument>
@@ -18225,6 +20426,8 @@
</description>
</method>
<method name="disconnect_node">
+ <return type="void">
+ </return>
<argument index="0" name="from" type="String">
</argument>
<argument index="1" name="from_port" type="int">
@@ -18293,6 +20496,8 @@
</description>
</method>
<method name="set_right_disconnects">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -18300,30 +20505,40 @@
</description>
</method>
<method name="set_scroll_ofs">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_selected">
- <argument index="0" name="node" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="node" type="Node">
</argument>
<description>
</description>
</method>
<method name="set_snap">
+ <return type="void">
+ </return>
<argument index="0" name="pixels" type="int">
</argument>
<description>
</description>
</method>
<method name="set_use_snap">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_zoom">
+ <return type="void">
+ </return>
<argument index="0" name="p_zoom" type="float">
</argument>
<description>
@@ -18440,11 +20655,15 @@
</description>
<methods>
<method name="clear_all_slots">
+ <return type="void">
+ </return>
<description>
Disable all input and output slots of the GraphNode.
</description>
</method>
<method name="clear_slot">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -18527,7 +20746,7 @@
</description>
</method>
<method name="get_overlay" qualifiers="const">
- <return type="int">
+ <return type="int" enum="GraphNode.Overlay">
</return>
<description>
</description>
@@ -18619,12 +20838,16 @@
</description>
</method>
<method name="set_comment">
+ <return type="void">
+ </return>
<argument index="0" name="comment" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -18632,24 +20855,32 @@
</description>
</method>
<method name="set_overlay">
- <argument index="0" name="overlay" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="overlay" type="int" enum="GraphNode.Overlay">
</argument>
<description>
</description>
</method>
<method name="set_resizeable">
+ <return type="void">
+ </return>
<argument index="0" name="resizeable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_selected">
+ <return type="void">
+ </return>
<argument index="0" name="selected" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_show_close_button">
+ <return type="void">
+ </return>
<argument index="0" name="show" type="bool">
</argument>
<description>
@@ -18657,6 +20888,8 @@
</description>
</method>
<method name="set_slot">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="enable_left" type="bool">
@@ -18671,14 +20904,16 @@
</argument>
<argument index="6" name="color_right" type="Color">
</argument>
- <argument index="7" name="custom_left" type="Object" default="NULL">
+ <argument index="7" name="custom_left" type="Texture" default="null">
</argument>
- <argument index="8" name="custom_right" type="Object" default="NULL">
+ <argument index="8" name="custom_right" type="Texture" default="null">
</argument>
<description>
</description>
</method>
<method name="set_title">
+ <return type="void">
+ </return>
<argument index="0" name="title" type="String">
</argument>
<description>
@@ -18787,6 +21022,8 @@
</description>
</method>
<method name="set_columns">
+ <return type="void">
+ </return>
<argument index="0" name="columns" type="int">
</argument>
<description>
@@ -18813,95 +21050,9 @@
<description>
</description>
<methods>
- <method name="area_get_bounds" qualifiers="const">
- <return type="Rect3">
- </return>
- <argument index="0" name="area" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_get_name" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="area" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_get_portal_disable_color" qualifiers="const">
- <return type="Color">
- </return>
- <argument index="0" name="area" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_get_portal_disable_distance" qualifiers="const">
- <return type="float">
- </return>
- <argument index="0" name="area" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_is_exterior_portal" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="area" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_set_exterior_portal">
- <argument index="0" name="area" type="int">
- </argument>
- <argument index="1" name="enable" type="bool">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_set_name">
- <argument index="0" name="area" type="int">
- </argument>
- <argument index="1" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_set_portal_disable_color">
- <argument index="0" name="area" type="int">
- </argument>
- <argument index="1" name="color" type="Color">
- </argument>
- <description>
- </description>
- </method>
- <method name="area_set_portal_disable_distance">
- <argument index="0" name="area" type="int">
- </argument>
- <argument index="1" name="distance" type="float">
- </argument>
- <description>
- </description>
- </method>
<method name="clear">
- <description>
- </description>
- </method>
- <method name="create_area">
- <return type="int">
+ <return type="void">
</return>
- <argument index="0" name="id" type="int">
- </argument>
- <argument index="1" name="area" type="Rect3">
- </argument>
- <description>
- </description>
- </method>
- <method name="erase_area">
- <argument index="0" name="area" type="int">
- </argument>
<description>
</description>
</method>
@@ -18930,7 +21081,7 @@
</description>
</method>
<method name="get_cell_size" qualifiers="const">
- <return type="float">
+ <return type="Vector3">
</return>
<description>
</description>
@@ -18971,19 +21122,17 @@
<description>
</description>
</method>
- <method name="get_unused_area_id" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
<method name="resource_changed">
- <argument index="0" name="resource" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="resource" type="Resource">
</argument>
<description>
</description>
</method>
<method name="set_cell_item">
+ <return type="void">
+ </return>
<argument index="0" name="x" type="int">
</argument>
<argument index="1" name="y" type="int">
@@ -18998,48 +21147,62 @@
</description>
</method>
<method name="set_cell_size">
- <argument index="0" name="size" type="float">
+ <return type="void">
+ </return>
+ <argument index="0" name="size" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_center_x">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_center_y">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_center_z">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_clip">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<argument index="1" name="clipabove" type="bool" default="true">
</argument>
<argument index="2" name="floor" type="int" default="0">
</argument>
- <argument index="3" name="axis" type="int" default="0">
+ <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="0">
</argument>
<description>
</description>
</method>
<method name="set_octant_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="int">
</argument>
<description>
</description>
</method>
<method name="set_theme">
+ <return type="void">
+ </return>
<argument index="0" name="theme" type="MeshLibrary">
</argument>
<description>
@@ -19047,7 +21210,7 @@
</method>
</methods>
<constants>
- <constant name="INVALID_CELL_ITEM" value="-1">
+ <constant name="INVALID_CELL_ITEM" value="-1" enum="">
</constant>
</constants>
</class>
@@ -19074,6 +21237,8 @@
</description>
</method>
<method name="set_initial_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="float">
</argument>
<description>
@@ -19081,6 +21246,8 @@
</description>
</method>
<method name="set_length">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
@@ -19133,6 +21300,8 @@
</theme_item>
<theme_item name="grabber_highlight" type="StyleBox">
</theme_item>
+ <theme_item name="grabber_pressed" type="StyleBox">
+ </theme_item>
<theme_item name="increment" type="Texture">
</theme_item>
<theme_item name="increment_highlight" type="Texture">
@@ -19223,12 +21392,14 @@
</description>
<methods>
<method name="close">
+ <return type="void">
+ </return>
<description>
Cloces the current connection, allows for reusal of [HTTPClient].
</description>
</method>
<method name="connect_to_host">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="host" type="String">
</argument>
@@ -19282,7 +21453,7 @@
</description>
</method>
<method name="get_status" qualifiers="const">
- <return type="int">
+ <return type="int" enum="HTTPClient.Status">
</return>
<description>
Returns a STATUS_* enum constant. Need to call [method poll] in order to get status updates.
@@ -19310,7 +21481,7 @@
</description>
</method>
<method name="poll">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<description>
This needs to be called in order to have any request processed. Check results with [method get_status]
@@ -19338,9 +21509,9 @@
</description>
</method>
<method name="request">
- <return type="int">
+ <return type="int" enum="Error">
</return>
- <argument index="0" name="method" type="int">
+ <argument index="0" name="method" type="int" enum="HTTPClient.Method">
</argument>
<argument index="1" name="url" type="String">
</argument>
@@ -19361,9 +21532,9 @@
</description>
</method>
<method name="request_raw">
- <return type="int">
+ <return type="int" enum="Error">
</return>
- <argument index="0" name="method" type="int">
+ <argument index="0" name="method" type="int" enum="HTTPClient.Method">
</argument>
<argument index="1" name="url" type="String">
</argument>
@@ -19378,7 +21549,7 @@
</description>
</method>
<method name="send_body_data">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="body" type="PoolByteArray">
</argument>
@@ -19387,7 +21558,7 @@
</description>
</method>
<method name="send_body_text">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="body" type="String">
</argument>
@@ -19396,6 +21567,8 @@
</description>
</method>
<method name="set_blocking_mode">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -19403,6 +21576,8 @@
</description>
</method>
<method name="set_connection">
+ <return type="void">
+ </return>
<argument index="0" name="connection" type="StreamPeer">
</argument>
<description>
@@ -19410,6 +21585,8 @@
</description>
</method>
<method name="set_read_chunk_size">
+ <return type="void">
+ </return>
<argument index="0" name="bytes" type="int">
</argument>
<description>
@@ -19566,6 +21743,8 @@
</description>
<methods>
<method name="cancel_request">
+ <return type="void">
+ </return>
<description>
Cancel the current request.
</description>
@@ -19599,7 +21778,7 @@
</description>
</method>
<method name="get_http_client_status" qualifiers="const">
- <return type="int">
+ <return type="int" enum="HTTPClient.Status">
</return>
<description>
Return the current status of the underlying [HTTPClient].
@@ -19620,15 +21799,15 @@
</description>
</method>
<method name="request">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="url" type="String">
</argument>
- <argument index="1" name="custom_headers" type="PoolStringArray" default="PoolStringArray([])">
+ <argument index="1" name="custom_headers" type="PoolStringArray" default="PoolStringArray( )">
</argument>
<argument index="2" name="ssl_validate_domain" type="bool" default="true">
</argument>
- <argument index="3" name="method" type="int" default="0">
+ <argument index="3" name="method" type="int" enum="HTTPClient.Method" default="0">
</argument>
<argument index="4" name="request_data" type="String" default="&quot;&quot;">
</argument>
@@ -19636,6 +21815,8 @@
</description>
</method>
<method name="set_body_size_limit">
+ <return type="void">
+ </return>
<argument index="0" name="bytes" type="int">
</argument>
<description>
@@ -19643,6 +21824,8 @@
</description>
</method>
<method name="set_download_file">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -19650,6 +21833,8 @@
</description>
</method>
<method name="set_max_redirects">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -19657,6 +21842,8 @@
</description>
</method>
<method name="set_use_threads">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -19734,7 +21921,7 @@
<method name="get_flag" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="flag" type="int">
+ <argument index="0" name="flag" type="int" enum="HingeJoint.Flag">
</argument>
<description>
</description>
@@ -19742,13 +21929,15 @@
<method name="get_param" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="HingeJoint.Param">
</argument>
<description>
</description>
</method>
<method name="set_flag">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="HingeJoint.Flag">
</argument>
<argument index="1" name="enabled" type="bool">
</argument>
@@ -19756,7 +21945,9 @@
</description>
</method>
<method name="set_param">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="HingeJoint.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -19822,12 +22013,16 @@
</description>
<methods>
<method name="clear_cache">
- <argument index="0" name="arg0" type="String" default="&quot;&quot;">
+ <return type="void">
+ </return>
+ <argument index="0" name="hostname" type="String" default="&quot;&quot;">
</argument>
<description>
</description>
</method>
<method name="erase_resolve_item">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
@@ -19850,7 +22045,7 @@
</description>
</method>
<method name="get_resolve_item_status" qualifiers="const">
- <return type="int">
+ <return type="int" enum="IP.ResolverStatus">
</return>
<argument index="0" name="id" type="int">
</argument>
@@ -19863,7 +22058,7 @@
</return>
<argument index="0" name="host" type="String">
</argument>
- <argument index="1" name="ip_type" type="int" default="3">
+ <argument index="1" name="ip_type" type="int" enum="IP.Type" default="3">
</argument>
<description>
Resolve a given hostname, blocking. Resolved hostname is returned as an IPv4 or IPv6 depending on "ip_type".
@@ -19874,7 +22069,7 @@
</return>
<argument index="0" name="host" type="String">
</argument>
- <argument index="1" name="ip_type" type="int" default="3">
+ <argument index="1" name="ip_type" type="int" enum="IP.Type" default="3">
</argument>
<description>
Create a queue item for resolving a given hostname to an IPv4 or IPv6 depending on "ip_type". The queue ID is returned, or RESOLVER_INVALID_ID on error.
@@ -19890,9 +22085,9 @@
</constant>
<constant name="RESOLVER_STATUS_ERROR" value="3">
</constant>
- <constant name="RESOLVER_MAX_QUERIES" value="32">
+ <constant name="RESOLVER_MAX_QUERIES" value="32" enum="">
</constant>
- <constant name="RESOLVER_INVALID_ID" value="-1">
+ <constant name="RESOLVER_INVALID_ID" value="-1" enum="">
</constant>
<constant name="TYPE_NONE" value="0">
</constant>
@@ -19923,6 +22118,8 @@
</description>
<methods>
<method name="blend_rect">
+ <return type="void">
+ </return>
<argument index="0" name="src" type="Image">
</argument>
<argument index="1" name="src_rect" type="Rect2">
@@ -19934,6 +22131,8 @@
</description>
</method>
<method name="blend_rect_mask">
+ <return type="void">
+ </return>
<argument index="0" name="src" type="Image">
</argument>
<argument index="1" name="mask" type="Image">
@@ -19947,6 +22146,8 @@
</description>
</method>
<method name="blit_rect">
+ <return type="void">
+ </return>
<argument index="0" name="src" type="Image">
</argument>
<argument index="1" name="src_rect" type="Rect2">
@@ -19958,6 +22159,8 @@
</description>
</method>
<method name="blit_rect_mask">
+ <return type="void">
+ </return>
<argument index="0" name="src" type="Image">
</argument>
<argument index="1" name="mask" type="Image">
@@ -19971,54 +22174,64 @@
</description>
</method>
<method name="clear_mipmaps">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="compress">
- <return type="int">
+ <return type="int" enum="Error">
</return>
- <argument index="0" name="mode" type="int">
+ <argument index="0" name="mode" type="int" enum="Image.CompressMode">
</argument>
- <argument index="1" name="arg1" type="int">
+ <argument index="1" name="source" type="int" enum="Image.CompressSource">
</argument>
- <argument index="2" name="arg2" type="float">
+ <argument index="2" name="lossy_quality" type="float">
</argument>
<description>
</description>
</method>
<method name="convert">
- <argument index="0" name="format" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="Image.Format">
</argument>
<description>
</description>
</method>
<method name="copy_from">
+ <return type="void">
+ </return>
<argument index="0" name="src" type="Image">
</argument>
<description>
</description>
</method>
<method name="create">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<argument index="1" name="height" type="int">
</argument>
<argument index="2" name="use_mipmaps" type="bool">
</argument>
- <argument index="3" name="format" type="int">
+ <argument index="3" name="format" type="int" enum="Image.Format">
</argument>
<description>
Create an empty image of a specific size and format.
</description>
</method>
<method name="create_from_data">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<argument index="1" name="height" type="int">
</argument>
<argument index="2" name="use_mipmaps" type="bool">
</argument>
- <argument index="3" name="format" type="int">
+ <argument index="3" name="format" type="int" enum="Image.Format">
</argument>
<argument index="4" name="data" type="PoolByteArray">
</argument>
@@ -20026,6 +22239,8 @@
</description>
</method>
<method name="crop">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<argument index="1" name="height" type="int">
@@ -20034,22 +22249,26 @@
</description>
</method>
<method name="decompress">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<description>
</description>
</method>
<method name="detect_alpha" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Image.AlphaMode">
</return>
<description>
</description>
</method>
<method name="expand_x2_hq2x">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="fill">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -20057,19 +22276,25 @@
</description>
</method>
<method name="fix_alpha_edges">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="flip_x">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="flip_y">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="generate_mipmaps">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<description>
</description>
@@ -20082,7 +22307,7 @@
</description>
</method>
<method name="get_format" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Image.Format">
</return>
<description>
Return the format of the [Image], one of [Image].FORMAT_*.
@@ -20122,6 +22347,12 @@
Return a new [Image] that is a copy of "area" in this [Image].
</description>
</method>
+ <method name="get_size" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_used_rect" qualifiers="const">
<return type="Rect2">
</return>
@@ -20161,7 +22392,7 @@
</description>
</method>
<method name="load">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -20170,35 +22401,45 @@
</description>
</method>
<method name="lock">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="normalmap_to_xy">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="premultiply_alpha">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="resize">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<argument index="1" name="height" type="int">
</argument>
- <argument index="2" name="interpolation" type="int" default="1">
+ <argument index="2" name="interpolation" type="int" enum="Image.Interpolation" default="1">
</argument>
<description>
</description>
</method>
<method name="resize_to_po2">
+ <return type="void">
+ </return>
<argument index="0" name="square" type="bool" default="false">
</argument>
<description>
</description>
</method>
<method name="save_png" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -20207,6 +22448,8 @@
</description>
</method>
<method name="set_pixel">
+ <return type="void">
+ </return>
<argument index="0" name="x" type="int">
</argument>
<argument index="1" name="y" type="int">
@@ -20217,14 +22460,20 @@
</description>
</method>
<method name="shrink_x2">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="srgb_to_linear">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="unlock">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -20349,11 +22598,13 @@
</description>
<methods>
<method name="create">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<argument index="1" name="height" type="int">
</argument>
- <argument index="2" name="format" type="int">
+ <argument index="2" name="format" type="int" enum="Image.Format">
</argument>
<argument index="3" name="flags" type="int" default="7">
</argument>
@@ -20364,6 +22615,8 @@
</description>
</method>
<method name="create_from_image">
+ <return type="void">
+ </return>
<argument index="0" name="image" type="Image">
</argument>
<argument index="1" name="flags" type="int" default="7">
@@ -20372,15 +22625,8 @@
Create a new [ImageTexture] from an [Image] with "flags" from [Texture].FLAG_*.
</description>
</method>
- <method name="get_data" qualifiers="const">
- <return type="Image">
- </return>
- <description>
- Return the [Image] of this [ImageTexture].
- </description>
- </method>
<method name="get_format" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Image.Format">
</return>
<description>
Return the format of the [ImageTexture], one of [Image].FORMAT_*.
@@ -20394,13 +22640,15 @@
</description>
</method>
<method name="get_storage" qualifiers="const">
- <return type="int">
+ <return type="int" enum="ImageTexture.Storage">
</return>
<description>
Return the storage type. One of [ImageTexture].STORAGE_*.
</description>
</method>
<method name="load">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -20408,6 +22656,8 @@
</description>
</method>
<method name="set_data">
+ <return type="void">
+ </return>
<argument index="0" name="image" type="Image">
</argument>
<description>
@@ -20415,6 +22665,8 @@
</description>
</method>
<method name="set_lossy_storage_quality">
+ <return type="void">
+ </return>
<argument index="0" name="quality" type="float">
</argument>
<description>
@@ -20422,13 +22674,17 @@
</description>
</method>
<method name="set_size_override">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_storage">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="ImageTexture.Storage">
</argument>
<description>
Set the storage type. One of [ImageTexture].STORAGE_*.
@@ -20455,6 +22711,8 @@
</description>
<methods>
<method name="add_sphere">
+ <return type="void">
+ </return>
<argument index="0" name="lats" type="int">
</argument>
<argument index="1" name="lons" type="int">
@@ -20464,10 +22722,12 @@
<argument index="3" name="add_uv" type="bool" default="true">
</argument>
<description>
- Simple helper to draw an uvsphere, with given latitudes, longitude and radius.
+ Simple helper to draw a uvsphere, with given latitudes, longitude and radius.
</description>
</method>
<method name="add_vertex">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector3">
</argument>
<description>
@@ -20475,9 +22735,11 @@
</description>
</method>
<method name="begin">
- <argument index="0" name="primitive" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="primitive" type="int" enum="Mesh.PrimitiveType">
</argument>
- <argument index="1" name="texture" type="Texture" default="NULL">
+ <argument index="1" name="texture" type="Texture" default="null">
</argument>
<description>
Begin drawing (And optionally pass a texture override). When done call end(). For more information on how this works, search for glBegin() glEnd() references.
@@ -20485,16 +22747,22 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear everything that was drawn using begin/end.
</description>
</method>
<method name="end">
+ <return type="void">
+ </return>
<description>
Call this when done adding a batch of geometry, otherwise it can't be displayed.
</description>
</method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -20502,6 +22770,8 @@
</description>
</method>
<method name="set_normal">
+ <return type="void">
+ </return>
<argument index="0" name="normal" type="Vector3">
</argument>
<description>
@@ -20509,6 +22779,8 @@
</description>
</method>
<method name="set_tangent">
+ <return type="void">
+ </return>
<argument index="0" name="tangent" type="Plane">
</argument>
<description>
@@ -20516,6 +22788,8 @@
</description>
</method>
<method name="set_uv">
+ <return type="void">
+ </return>
<argument index="0" name="uv" type="Vector2">
</argument>
<description>
@@ -20523,6 +22797,8 @@
</description>
</method>
<method name="set_uv2">
+ <return type="void">
+ </return>
<argument index="0" name="uv" type="Vector2">
</argument>
<description>
@@ -20542,6 +22818,8 @@
</description>
<methods>
<method name="action_press">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
<description>
@@ -20549,6 +22827,8 @@
</description>
</method>
<method name="action_release">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
<description>
@@ -20556,6 +22836,8 @@
</description>
</method>
<method name="add_joy_mapping">
+ <return type="void">
+ </return>
<argument index="0" name="mapping" type="String">
</argument>
<argument index="1" name="update_existing" type="bool" default="false">
@@ -20692,7 +22974,7 @@
</description>
</method>
<method name="get_mouse_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Input.MouseMode">
</return>
<description>
Return the mouse mode. See the constants for more information.
@@ -20762,12 +23044,16 @@
</description>
</method>
<method name="parse_input_event">
- <argument index="0" name="event" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="event" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="remove_joy_mapping">
+ <return type="void">
+ </return>
<argument index="0" name="guid" type="String">
</argument>
<description>
@@ -20775,22 +23061,27 @@
</description>
</method>
<method name="set_custom_mouse_cursor">
- <argument index="0" name="image" type="Texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="image" type="Resource">
</argument>
- <argument index="1" name="hotspot" type="Vector2" default="Vector2(0, 0)">
+ <argument index="1" name="hotspot" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
- Set a custom mouse cursor image, which is only visible inside the game window. The hotspot can also be specified.
</description>
</method>
<method name="set_mouse_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Input.MouseMode">
</argument>
<description>
Set the mouse mode. See the constants for more information.
</description>
</method>
<method name="start_joy_vibration">
+ <return type="void">
+ </return>
<argument index="0" name="device" type="int">
</argument>
<argument index="1" name="weak_magnitude" type="float">
@@ -20805,6 +23096,8 @@
</description>
</method>
<method name="stop_joy_vibration">
+ <return type="void">
+ </return>
<argument index="0" name="device" type="int">
</argument>
<description>
@@ -20812,6 +23105,8 @@
</description>
</method>
<method name="warp_mouse_pos">
+ <return type="void">
+ </return>
<argument index="0" name="to" type="Vector2">
</argument>
<description>
@@ -20936,12 +23231,16 @@
</description>
</method>
<method name="set_device">
+ <return type="void">
+ </return>
<argument index="0" name="device" type="int">
</argument>
<description>
</description>
</method>
<method name="set_id">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
@@ -20960,7 +23259,7 @@
</return>
<argument index="0" name="xform" type="Transform2D">
</argument>
- <argument index="1" name="local_ofs" type="Vector2" default="Vector2(0, 0)">
+ <argument index="1" name="local_ofs" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
</description>
@@ -20987,12 +23286,16 @@
</description>
</method>
<method name="set_action">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
<description>
</description>
</method>
<method name="set_pressed">
+ <return type="void">
+ </return>
<argument index="0" name="pressed" type="bool">
</argument>
<description>
@@ -21028,18 +23331,24 @@
</description>
</method>
<method name="set_button_index">
+ <return type="void">
+ </return>
<argument index="0" name="button_index" type="int">
</argument>
<description>
</description>
</method>
<method name="set_pressed">
+ <return type="void">
+ </return>
<argument index="0" name="pressed" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_pressure">
+ <return type="void">
+ </return>
<argument index="0" name="pressure" type="float">
</argument>
<description>
@@ -21080,12 +23389,16 @@
</description>
</method>
<method name="set_axis">
+ <return type="void">
+ </return>
<argument index="0" name="axis" type="int">
</argument>
<description>
</description>
</method>
<method name="set_axis_value">
+ <return type="void">
+ </return>
<argument index="0" name="axis_value" type="float">
</argument>
<description>
@@ -21129,24 +23442,32 @@
</description>
</method>
<method name="set_echo">
+ <return type="void">
+ </return>
<argument index="0" name="echo" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_pressed">
+ <return type="void">
+ </return>
<argument index="0" name="pressed" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_scancode">
+ <return type="void">
+ </return>
<argument index="0" name="scancode" type="int">
</argument>
<description>
</description>
</method>
<method name="set_unicode">
+ <return type="void">
+ </return>
<argument index="0" name="unicode" type="int">
</argument>
<description>
@@ -21154,7 +23475,7 @@
</method>
</methods>
<members>
- <member name="echo" type="int" setter="set_echo" getter="is_echo" brief="">
+ <member name="echo" type="bool" setter="set_echo" getter="is_echo" brief="">
Echo state of the key, i.e. whether it's a repeat event or not.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
@@ -21196,18 +23517,24 @@
</description>
</method>
<method name="set_button_mask">
+ <return type="void">
+ </return>
<argument index="0" name="button_mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_global_position">
+ <return type="void">
+ </return>
<argument index="0" name="global_position" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_position">
+ <return type="void">
+ </return>
<argument index="0" name="position" type="Vector2">
</argument>
<description>
@@ -21254,24 +23581,32 @@
</description>
</method>
<method name="set_button_index">
+ <return type="void">
+ </return>
<argument index="0" name="button_index" type="int">
</argument>
<description>
</description>
</method>
<method name="set_doubleclick">
+ <return type="void">
+ </return>
<argument index="0" name="doubleclick" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_factor">
+ <return type="void">
+ </return>
<argument index="0" name="factor" type="float">
</argument>
<description>
</description>
</method>
<method name="set_pressed">
+ <return type="void">
+ </return>
<argument index="0" name="pressed" type="bool">
</argument>
<description>
@@ -21314,12 +23649,16 @@
</description>
</method>
<method name="set_relative">
+ <return type="void">
+ </return>
<argument index="0" name="relative" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_speed">
+ <return type="void">
+ </return>
<argument index="0" name="speed" type="Vector2">
</argument>
<description>
@@ -21369,24 +23708,32 @@
</description>
</method>
<method name="set_index">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<description>
</description>
</method>
<method name="set_position">
+ <return type="void">
+ </return>
<argument index="0" name="position" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_relative">
+ <return type="void">
+ </return>
<argument index="0" name="relative" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_speed">
+ <return type="void">
+ </return>
<argument index="0" name="speed" type="Vector2">
</argument>
<description>
@@ -21430,18 +23777,24 @@
</description>
</method>
<method name="set_index">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<description>
</description>
</method>
<method name="set_position">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_pressed">
+ <return type="void">
+ </return>
<argument index="0" name="pressed" type="bool">
</argument>
<description>
@@ -21500,30 +23853,40 @@
</description>
</method>
<method name="set_alt">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_command">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_control">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_metakey">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_shift">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -21558,18 +23921,22 @@
</description>
<methods>
<method name="action_add_event">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
- <argument index="1" name="event" type="Object">
+ <argument index="1" name="event" type="InputEvent">
</argument>
<description>
Add an [InputEvent] to an action. This [InputEvent] will trigger the action.
</description>
</method>
<method name="action_erase_event">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
- <argument index="1" name="event" type="Object">
+ <argument index="1" name="event" type="InputEvent">
</argument>
<description>
Remove an [InputEvent] from an action.
@@ -21580,13 +23947,15 @@
</return>
<argument index="0" name="action" type="String">
</argument>
- <argument index="1" name="event" type="Object">
+ <argument index="1" name="event" type="InputEvent">
</argument>
<description>
Whether an action has an [InputEvent] associated with it.
</description>
</method>
<method name="add_action">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
<description>
@@ -21594,6 +23963,8 @@
</description>
</method>
<method name="erase_action">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
<description>
@@ -21603,7 +23974,7 @@
<method name="event_is_action" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="event" type="Object">
+ <argument index="0" name="event" type="InputEvent">
</argument>
<argument index="1" name="action" type="String">
</argument>
@@ -21637,6 +24008,8 @@
</description>
</method>
<method name="load_from_globals">
+ <return type="void">
+ </return>
<description>
Clear the [InputMap] and load it anew from [ProjectSettings].
</description>
@@ -21670,7 +24043,9 @@
</description>
</method>
<method name="replace_by_instance">
- <argument index="0" name="custom_scene" type="PackedScene" default="NULL">
+ <return type="void">
+ </return>
+ <argument index="0" name="custom_scene" type="PackedScene" default="null">
</argument>
<description>
Replace this placeholder by the scene handed as an argument, or the original scene if no argument is given. As for all resources, the scene is loaded only if it's not loaded already. By manually loading the scene beforehand, delays caused by this function can be avoided.
@@ -21705,24 +24080,32 @@
</description>
</method>
<method name="set_interpolation_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="target_path" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_speed">
+ <return type="void">
+ </return>
<argument index="0" name="speed" type="float">
</argument>
<description>
</description>
</method>
<method name="set_target">
- <argument index="0" name="target" type="Camera">
+ <return type="void">
+ </return>
+ <argument index="0" name="target" type="Object">
</argument>
<description>
</description>
</method>
<method name="set_target_path">
+ <return type="void">
+ </return>
<argument index="0" name="target_path" type="NodePath">
</argument>
<description>
@@ -21752,6 +24135,8 @@
</description>
<methods>
<method name="add_icon_item">
+ <return type="void">
+ </return>
<argument index="0" name="icon" type="Texture">
</argument>
<argument index="1" name="selectable" type="bool" default="true">
@@ -21761,9 +24146,11 @@
</description>
</method>
<method name="add_item">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
- <argument index="1" name="icon" type="Texture" default="NULL">
+ <argument index="1" name="icon" type="Texture" default="null">
</argument>
<argument index="2" name="selectable" type="bool" default="true">
</argument>
@@ -21773,11 +24160,15 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Remove all items from the list.
</description>
</method>
<method name="ensure_current_is_visible">
+ <return type="void">
+ </return>
<description>
Ensure selection is visible, adjusting the scroll position as necessary.
</description>
@@ -21803,7 +24194,7 @@
</description>
</method>
<method name="get_icon_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="ItemList.IconMode">
</return>
<description>
</description>
@@ -21897,7 +24288,7 @@
</description>
</method>
<method name="get_select_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="ItemList.SelectMode">
</return>
<description>
</description>
@@ -21910,12 +24301,18 @@
</description>
</method>
<method name="get_v_scroll">
- <return type="Object">
+ <return type="VScrollBar">
</return>
<description>
Returns the current vertical scroll bar for the List.
</description>
</method>
+ <method name="has_auto_height" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_item_disabled" qualifiers="const">
<return type="bool">
</return>
@@ -21944,7 +24341,7 @@
</description>
</method>
<method name="is_same_column_width" qualifiers="const">
- <return type="int">
+ <return type="bool">
</return>
<description>
Returns whether or not all columns of the list are of the same size.
@@ -21960,6 +24357,8 @@
</description>
</method>
<method name="remove_item">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -21967,6 +24366,8 @@
</description>
</method>
<method name="select">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="single" type="bool" default="true">
@@ -21977,13 +24378,25 @@
</description>
</method>
<method name="set_allow_rmb_select">
+ <return type="void">
+ </return>
<argument index="0" name="allow" type="bool">
</argument>
<description>
Allow (or disallow) selection of (selectable) items in the list using right mouse button.
</description>
</method>
+ <method name="set_auto_height">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_fixed_column_width">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="int">
</argument>
<description>
@@ -21991,24 +24404,32 @@
</description>
</method>
<method name="set_fixed_icon_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_icon_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="ItemList.IconMode">
</argument>
<description>
</description>
</method>
<method name="set_icon_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="float">
</argument>
<description>
</description>
</method>
<method name="set_item_custom_bg_color">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="custom_bg_color" type="Color">
@@ -22017,6 +24438,8 @@
</description>
</method>
<method name="set_item_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="disabled" type="bool">
@@ -22027,6 +24450,8 @@
</description>
</method>
<method name="set_item_icon">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="icon" type="Texture">
@@ -22036,6 +24461,8 @@
</description>
</method>
<method name="set_item_icon_region">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="rect" type="Rect2">
@@ -22044,6 +24471,8 @@
</description>
</method>
<method name="set_item_metadata">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="metadata" type="Variant">
@@ -22053,6 +24482,8 @@
</description>
</method>
<method name="set_item_selectable">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="selectable" type="bool">
@@ -22062,6 +24493,8 @@
</description>
</method>
<method name="set_item_text">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="text" type="String">
@@ -22071,6 +24504,8 @@
</description>
</method>
<method name="set_item_tooltip">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="tooltip" type="String">
@@ -22080,6 +24515,8 @@
</description>
</method>
<method name="set_item_tooltip_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -22089,6 +24526,8 @@
</description>
</method>
<method name="set_max_columns">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -22096,6 +24535,8 @@
</description>
</method>
<method name="set_max_text_lines">
+ <return type="void">
+ </return>
<argument index="0" name="lines" type="int">
</argument>
<description>
@@ -22103,6 +24544,8 @@
</description>
</method>
<method name="set_same_column_width">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -22110,17 +24553,23 @@
</description>
</method>
<method name="set_select_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="ItemList.SelectMode">
</argument>
<description>
</description>
</method>
<method name="sort_items_by_text">
+ <return type="void">
+ </return>
<description>
Sorts items in the list by their text.
</description>
</method>
<method name="unselect">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -22131,9 +24580,11 @@
<members>
<member name="allow_rmb_select" type="bool" setter="set_allow_rmb_select" getter="get_allow_rmb_select" brief="">
</member>
+ <member name="auto_height" type="bool" setter="set_auto_height" getter="has_auto_height" brief="">
+ </member>
<member name="fixed_column_width" type="int" setter="set_fixed_column_width" getter="get_fixed_column_width" brief="">
</member>
- <member name="icon_mode" type="int" setter="set_icon_mode" getter="get_icon_mode" brief="">
+ <member name="icon_mode" type="int" setter="set_icon_mode" getter="get_icon_mode" brief="" enum="ItemList.IconMode">
</member>
<member name="icon_scale" type="float" setter="set_icon_scale" getter="get_icon_scale" brief="">
</member>
@@ -22145,7 +24596,7 @@
</member>
<member name="same_column_width" type="bool" setter="set_same_column_width" getter="is_same_column_width" brief="">
</member>
- <member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" brief="">
+ <member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" brief="" enum="ItemList.SelectMode">
</member>
</members>
<signals>
@@ -22256,24 +24707,32 @@
</description>
</method>
<method name="set_exclude_nodes_from_collision">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_node_a">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_node_b">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_solver_priority">
+ <return type="void">
+ </return>
<argument index="0" name="priority" type="int">
</argument>
<description>
@@ -22328,18 +24787,24 @@
</description>
</method>
<method name="set_bias">
+ <return type="void">
+ </return>
<argument index="0" name="bias" type="float">
</argument>
<description>
</description>
</method>
<method name="set_exclude_nodes_from_collision">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_node_a">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="NodePath">
</argument>
<description>
@@ -22347,6 +24812,8 @@
</description>
</method>
<method name="set_node_b">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="NodePath">
</argument>
<description>
@@ -22394,6 +24861,8 @@
</description>
</method>
<method name="get_collision_collider_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="collision" type="int">
</argument>
<description>
@@ -22522,7 +24991,7 @@
</return>
<argument index="0" name="linear_velocity" type="Vector3">
</argument>
- <argument index="1" name="floor_normal" type="Vector3" default="Vector3(0, 0, 0)">
+ <argument index="1" name="floor_normal" type="Vector3" default="Vector3( 0, 0, 0 )">
</argument>
<argument index="2" name="slope_stop_min_velocity" type="float" default="0.05">
</argument>
@@ -22534,6 +25003,8 @@
</description>
</method>
<method name="set_safe_margin">
+ <return type="void">
+ </return>
<argument index="0" name="pixels" type="float">
</argument>
<description>
@@ -22584,6 +25055,8 @@
</description>
</method>
<method name="get_collision_collider_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="collision" type="int">
</argument>
<description>
@@ -22713,7 +25186,7 @@
</return>
<argument index="0" name="linear_velocity" type="Vector2">
</argument>
- <argument index="1" name="floor_normal" type="Vector2" default="Vector2(0, 0)">
+ <argument index="1" name="floor_normal" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<argument index="2" name="slope_stop_min_velocity" type="float" default="5">
</argument>
@@ -22725,6 +25198,8 @@
</description>
</method>
<method name="set_safe_margin">
+ <return type="void">
+ </return>
<argument index="0" name="pixels" type="float">
</argument>
<description>
@@ -22758,7 +25233,7 @@
</description>
<methods>
<method name="get_align" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Label.Align">
</return>
<description>
Return the alignment mode (any of the ALIGN_* enumeration values).
@@ -22814,7 +25289,7 @@
</description>
</method>
<method name="get_valign" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Label.VAlign">
</return>
<description>
Return the vertical alignment mode (any of the VALIGN_* enumeration values).
@@ -22855,13 +25330,17 @@
</description>
</method>
<method name="set_align">
- <argument index="0" name="align" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="align" type="int" enum="Label.Align">
</argument>
<description>
Sets the alignment mode to any of the ALIGN_* enumeration values.
</description>
</method>
<method name="set_autowrap">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -22869,6 +25348,8 @@
</description>
</method>
<method name="set_clip_text">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -22876,6 +25357,8 @@
</description>
</method>
<method name="set_lines_skipped">
+ <return type="void">
+ </return>
<argument index="0" name="lines_skipped" type="int">
</argument>
<description>
@@ -22883,6 +25366,8 @@
</description>
</method>
<method name="set_max_lines_visible">
+ <return type="void">
+ </return>
<argument index="0" name="lines_visible" type="int">
</argument>
<description>
@@ -22890,6 +25375,8 @@
</description>
</method>
<method name="set_percent_visible">
+ <return type="void">
+ </return>
<argument index="0" name="percent_visible" type="float">
</argument>
<description>
@@ -22897,6 +25384,8 @@
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -22904,6 +25393,8 @@
</description>
</method>
<method name="set_uppercase">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -22911,13 +25402,17 @@
</description>
</method>
<method name="set_valign">
- <argument index="0" name="valign" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="valign" type="int" enum="Label.VAlign">
</argument>
<description>
Sets the vertical alignment mode to any of the VALIGN_* enumeration values.
</description>
</method>
<method name="set_visible_characters">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -22926,7 +25421,7 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_align" getter="get_align" brief="">
+ <member name="align" type="int" setter="set_align" getter="get_align" brief="" enum="Label.Align">
</member>
<member name="autowrap" type="bool" setter="set_autowrap" getter="has_autowrap" brief="">
</member>
@@ -22942,7 +25437,7 @@
</member>
<member name="uppercase" type="bool" setter="set_uppercase" getter="is_uppercase" brief="">
</member>
- <member name="valign" type="int" setter="set_valign" getter="get_valign" brief="">
+ <member name="valign" type="int" setter="set_valign" getter="get_valign" brief="" enum="Label.VAlign">
</member>
</members>
<constants>
@@ -22980,6 +25475,8 @@
</theme_item>
<theme_item name="line_spacing" type="int">
</theme_item>
+ <theme_item name="normal" type="StyleBox">
+ </theme_item>
<theme_item name="shadow_as_outline" type="int">
</theme_item>
<theme_item name="shadow_offset_x" type="int">
@@ -23009,6 +25506,8 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear the [LargeTexture].
</description>
@@ -23039,6 +25538,8 @@
</description>
</method>
<method name="set_piece_offset">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="ofs" type="Vector2">
@@ -23048,6 +25549,8 @@
</description>
</method>
<method name="set_piece_texture">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="texture" type="Texture">
@@ -23057,6 +25560,8 @@
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
@@ -23094,7 +25599,7 @@
<method name="get_param" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="Light.Param">
</argument>
<description>
</description>
@@ -23105,6 +25610,12 @@
<description>
</description>
</method>
+ <method name="get_shadow_reverse_cull_face" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="has_shadow" qualifiers="const">
<return type="bool">
</return>
@@ -23124,31 +25635,41 @@
</description>
</method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_cull_mask">
+ <return type="void">
+ </return>
<argument index="0" name="cull_mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_editor_only">
+ <return type="void">
+ </return>
<argument index="0" name="editor_only" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_negative">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_param">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="Light.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -23156,17 +25677,29 @@
</description>
</method>
<method name="set_shadow">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_shadow_color">
+ <return type="void">
+ </return>
<argument index="0" name="shadow_color" type="Color">
</argument>
<description>
</description>
</method>
+ <method name="set_shadow_reverse_cull_face">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only" brief="">
@@ -23191,6 +25724,8 @@
</member>
<member name="shadow_max_distance" type="float" setter="set_param" getter="get_param" brief="">
</member>
+ <member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face" brief="">
+ </member>
</members>
<constants>
<constant name="PARAM_ENERGY" value="0">
@@ -23219,7 +25754,7 @@
</constant>
<constant name="PARAM_SHADOW_BIAS" value="12">
</constant>
- <constant name="PARAM_MAX" value="13">
+ <constant name="PARAM_MAX" value="14">
</constant>
</constants>
</class>
@@ -23279,7 +25814,7 @@
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Light2D.Mode">
</return>
<description>
Return the current mode set to the Light2D.
@@ -23300,7 +25835,7 @@
</description>
</method>
<method name="get_shadow_filter" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Light2D.ShadowFilter">
</return>
<description>
</description>
@@ -23318,7 +25853,7 @@
</description>
</method>
<method name="get_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
Return the texture of the Light2D.
@@ -23373,6 +25908,8 @@
</description>
</method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -23380,12 +25917,16 @@
</description>
</method>
<method name="set_editor_only">
+ <return type="void">
+ </return>
<argument index="0" name="editor_only" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -23393,6 +25934,8 @@
</description>
</method>
<method name="set_energy">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
@@ -23400,6 +25943,8 @@
</description>
</method>
<method name="set_height">
+ <return type="void">
+ </return>
<argument index="0" name="height" type="float">
</argument>
<description>
@@ -23407,6 +25952,8 @@
</description>
</method>
<method name="set_item_cull_mask">
+ <return type="void">
+ </return>
<argument index="0" name="item_cull_mask" type="int">
</argument>
<description>
@@ -23414,6 +25961,8 @@
</description>
</method>
<method name="set_item_shadow_cull_mask">
+ <return type="void">
+ </return>
<argument index="0" name="item_shadow_cull_mask" type="int">
</argument>
<description>
@@ -23421,6 +25970,8 @@
</description>
</method>
<method name="set_layer_range_max">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
@@ -23428,6 +25979,8 @@
</description>
</method>
<method name="set_layer_range_min">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
@@ -23435,13 +25988,17 @@
</description>
</method>
<method name="set_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Light2D.Mode">
</argument>
<description>
Set the behaviour mode of the Light2D. Use constants defined in the constants section.
</description>
</method>
<method name="set_shadow_buffer_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="int">
</argument>
<description>
@@ -23449,6 +26006,8 @@
</description>
</method>
<method name="set_shadow_color">
+ <return type="void">
+ </return>
<argument index="0" name="shadow_color" type="Color">
</argument>
<description>
@@ -23456,6 +26015,8 @@
</description>
</method>
<method name="set_shadow_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -23463,31 +26024,41 @@
</description>
</method>
<method name="set_shadow_filter">
- <argument index="0" name="filter" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="filter" type="int" enum="Light2D.ShadowFilter">
</argument>
<description>
</description>
</method>
<method name="set_shadow_gradient_length">
+ <return type="void">
+ </return>
<argument index="0" name="multiplier" type="float">
</argument>
<description>
</description>
</method>
<method name="set_shadow_smooth">
+ <return type="void">
+ </return>
<argument index="0" name="smooth" type="float">
</argument>
<description>
</description>
</method>
<method name="set_texture">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
Set the texture of the Light2D.
</description>
</method>
<method name="set_texture_offset">
+ <return type="void">
+ </return>
<argument index="0" name="texture_offset" type="Vector2">
</argument>
<description>
@@ -23495,6 +26066,8 @@
</description>
</method>
<method name="set_texture_scale">
+ <return type="void">
+ </return>
<argument index="0" name="texture_scale" type="float">
</argument>
<description>
@@ -23502,6 +26075,8 @@
</description>
</method>
<method name="set_z_range_max">
+ <return type="void">
+ </return>
<argument index="0" name="z" type="int">
</argument>
<description>
@@ -23509,6 +26084,8 @@
</description>
</method>
<method name="set_z_range_min">
+ <return type="void">
+ </return>
<argument index="0" name="z" type="int">
</argument>
<description>
@@ -23525,7 +26102,7 @@
</member>
<member name="energy" type="float" setter="set_energy" getter="get_energy" brief="">
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="Light2D.Mode">
</member>
<member name="offset" type="Vector2" setter="set_texture_offset" getter="get_texture_offset" brief="">
</member>
@@ -23541,15 +26118,13 @@
</member>
<member name="range_z_min" type="int" setter="set_z_range_min" getter="get_z_range_min" brief="">
</member>
- <member name="scale" type="float" setter="set_texture_scale" getter="get_texture_scale" brief="">
- </member>
<member name="shadow_buffer_size" type="int" setter="set_shadow_buffer_size" getter="get_shadow_buffer_size" brief="">
</member>
<member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" brief="">
</member>
<member name="shadow_enabled" type="bool" setter="set_shadow_enabled" getter="is_shadow_enabled" brief="">
</member>
- <member name="shadow_filter" type="float" setter="set_shadow_filter" getter="get_shadow_filter" brief="">
+ <member name="shadow_filter" type="int" setter="set_shadow_filter" getter="get_shadow_filter" brief="" enum="Light2D.ShadowFilter">
</member>
<member name="shadow_filter_smooth" type="float" setter="set_shadow_smooth" getter="get_shadow_smooth" brief="">
</member>
@@ -23559,6 +26134,8 @@
</member>
<member name="texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
+ <member name="texture_scale" type="float" setter="set_texture_scale" getter="get_texture_scale" brief="">
+ </member>
</members>
<constants>
<constant name="MODE_ADD" value="0">
@@ -23598,6 +26175,8 @@
</description>
</method>
<method name="set_occluder_light_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
@@ -23605,6 +26184,8 @@
</description>
</method>
<method name="set_occluder_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="polygon" type="OccluderPolygon2D">
</argument>
<description>
@@ -23628,13 +26209,15 @@
</description>
<methods>
<method name="add_point">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="get_begin_cap_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="LineCapMode">
</return>
<description>
</description>
@@ -23646,19 +26229,19 @@
</description>
</method>
<method name="get_end_cap_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="LineCapMode">
</return>
<description>
</description>
</method>
<method name="get_gradient" qualifiers="const">
- <return type="Object">
+ <return type="Gradient">
</return>
<description>
</description>
</method>
<method name="get_joint_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="LineJointMode">
</return>
<description>
</description>
@@ -23696,13 +26279,13 @@
</description>
</method>
<method name="get_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
</method>
<method name="get_texture_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="LineTextureMode">
</return>
<description>
</description>
@@ -23714,42 +26297,56 @@
</description>
</method>
<method name="remove_point">
+ <return type="void">
+ </return>
<argument index="0" name="i" type="int">
</argument>
<description>
</description>
</method>
<method name="set_begin_cap_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="LineCapMode">
</argument>
<description>
</description>
</method>
<method name="set_default_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_end_cap_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="LineCapMode">
</argument>
<description>
</description>
</method>
<method name="set_gradient">
- <argument index="0" name="color" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="color" type="Gradient">
</argument>
<description>
</description>
</method>
<method name="set_joint_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="LineJointMode">
</argument>
<description>
</description>
</method>
<method name="set_point_pos">
+ <return type="void">
+ </return>
<argument index="0" name="i" type="int">
</argument>
<argument index="1" name="pos" type="Vector2">
@@ -23758,36 +26355,48 @@
</description>
</method>
<method name="set_points">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<description>
</description>
</method>
<method name="set_round_precision">
+ <return type="void">
+ </return>
<argument index="0" name="precision" type="int">
</argument>
<description>
</description>
</method>
<method name="set_sharp_limit">
+ <return type="void">
+ </return>
<argument index="0" name="limit" type="float">
</argument>
<description>
</description>
</method>
<method name="set_texture">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_texture_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="LineTextureMode">
</argument>
<description>
</description>
</method>
<method name="set_width">
+ <return type="void">
+ </return>
<argument index="0" name="width" type="float">
</argument>
<description>
@@ -23795,15 +26404,15 @@
</method>
</methods>
<members>
- <member name="begin_cap_mode" type="int" setter="set_begin_cap_mode" getter="get_begin_cap_mode" brief="">
+ <member name="begin_cap_mode" type="int" setter="set_begin_cap_mode" getter="get_begin_cap_mode" brief="" enum="LineCapMode">
</member>
<member name="default_color" type="Color" setter="set_default_color" getter="get_default_color" brief="">
</member>
- <member name="end_cap_mode" type="int" setter="set_end_cap_mode" getter="get_end_cap_mode" brief="">
+ <member name="end_cap_mode" type="int" setter="set_end_cap_mode" getter="get_end_cap_mode" brief="" enum="LineCapMode">
</member>
<member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient" brief="">
</member>
- <member name="joint_mode" type="int" setter="set_joint_mode" getter="get_joint_mode" brief="">
+ <member name="joint_mode" type="int" setter="set_joint_mode" getter="get_joint_mode" brief="" enum="LineJointMode">
</member>
<member name="points" type="PoolVector2Array" setter="set_points" getter="get_points" brief="">
</member>
@@ -23813,7 +26422,7 @@
</member>
<member name="texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="texture_mode" type="int" setter="set_texture_mode" getter="get_texture_mode" brief="">
+ <member name="texture_mode" type="int" setter="set_texture_mode" getter="get_texture_mode" brief="" enum="LineTextureMode">
</member>
<member name="width" type="float" setter="set_width" getter="get_width" brief="">
</member>
@@ -23846,6 +26455,8 @@
</description>
<methods>
<method name="append_at_cursor">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -23853,6 +26464,8 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear the [LineEdit] text.
</description>
@@ -23872,6 +26485,8 @@
</description>
</method>
<method name="cursor_set_blink_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -23879,6 +26494,8 @@
</description>
</method>
<method name="cursor_set_blink_speed">
+ <return type="void">
+ </return>
<argument index="0" name="blink_speed" type="float">
</argument>
<description>
@@ -23886,7 +26503,7 @@
</description>
</method>
<method name="get_align" qualifiers="const">
- <return type="int">
+ <return type="int" enum="LineEdit.Align">
</return>
<description>
</description>
@@ -23951,12 +26568,16 @@
</description>
</method>
<method name="menu_option">
+ <return type="void">
+ </return>
<argument index="0" name="option" type="int">
</argument>
<description>
</description>
</method>
<method name="select">
+ <return type="void">
+ </return>
<argument index="0" name="from" type="int" default="0">
</argument>
<argument index="1" name="to" type="int" default="-1">
@@ -23965,17 +26586,23 @@
</description>
</method>
<method name="select_all">
+ <return type="void">
+ </return>
<description>
Select the whole string.
</description>
</method>
<method name="set_align">
- <argument index="0" name="align" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="align" type="int" enum="LineEdit.Align">
</argument>
<description>
</description>
</method>
<method name="set_cursor_pos">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="int">
</argument>
<description>
@@ -23983,6 +26610,8 @@
</description>
</method>
<method name="set_editable">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -23990,12 +26619,16 @@
</description>
</method>
<method name="set_expand_to_text_length">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_max_length">
+ <return type="void">
+ </return>
<argument index="0" name="chars" type="int">
</argument>
<description>
@@ -24003,18 +26636,24 @@
</description>
</method>
<method name="set_placeholder">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
</description>
</method>
<method name="set_placeholder_alpha">
+ <return type="void">
+ </return>
<argument index="0" name="alpha" type="float">
</argument>
<description>
</description>
</method>
<method name="set_secret">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -24022,6 +26661,8 @@
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -24030,7 +26671,7 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_align" getter="get_align" brief="">
+ <member name="align" type="int" setter="set_align" getter="get_align" brief="" enum="LineEdit.Align">
</member>
<member name="caret_blink" type="bool" setter="cursor_set_blink_enabled" getter="cursor_get_blink_enabled" brief="">
</member>
@@ -24040,7 +26681,7 @@
</member>
<member name="expand_to_len" type="bool" setter="set_expand_to_text_length" getter="get_expand_to_text_length" brief="">
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" brief="">
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" brief="" enum="Control.FocusMode">
</member>
<member name="max_length" type="int" setter="set_max_length" getter="get_max_length" brief="">
</member>
@@ -24137,6 +26778,8 @@
</description>
</method>
<method name="set_d">
+ <return type="void">
+ </return>
<argument index="0" name="d" type="float">
</argument>
<description>
@@ -24144,6 +26787,8 @@
</description>
</method>
<method name="set_normal">
+ <return type="void">
+ </return>
<argument index="0" name="normal" type="Vector2">
</argument>
<description>
@@ -24176,13 +26821,15 @@
</description>
</method>
<method name="get_underline_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="LinkButton.UnderlineMode">
</return>
<description>
Returns the underline mode for this button.
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -24190,7 +26837,9 @@
</description>
</method>
<method name="set_underline_mode">
- <argument index="0" name="underline_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="underline_mode" type="int" enum="LinkButton.UnderlineMode">
</argument>
<description>
Sets the underline mode for this button, the argument must be one of the [LinkButton] constants (see constants section).
@@ -24200,7 +26849,7 @@
<members>
<member name="text" type="String" setter="set_text" getter="get_text" brief="">
</member>
- <member name="underline" type="int" setter="set_underline_mode" getter="get_underline_mode" brief="">
+ <member name="underline" type="int" setter="set_underline_mode" getter="get_underline_mode" brief="" enum="LinkButton.UnderlineMode">
</member>
</members>
<constants>
@@ -24234,6 +26883,8 @@
</description>
<methods>
<method name="clear_current">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -24250,6 +26901,8 @@
</description>
</method>
<method name="make_current">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -24266,6 +26919,8 @@
</description>
<methods>
<method name="_drop_files" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="files" type="PoolStringArray">
</argument>
<argument index="1" name="screen" type="int">
@@ -24274,38 +26929,52 @@
</description>
</method>
<method name="_finalize" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="_idle" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<description>
</description>
</method>
<method name="_initialize" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="_input_event" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="ev" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="_input_text" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
</description>
</method>
<method name="_iteration" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<description>
</description>
</method>
<method name="finish">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -24318,16 +26987,22 @@
</description>
</method>
<method name="init">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="input_event">
- <argument index="0" name="ev" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="ev" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="input_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -24343,19 +27018,23 @@
</method>
</methods>
<constants>
- <constant name="NOTIFICATION_WM_MOUSE_ENTER" value="2">
+ <constant name="NOTIFICATION_WM_MOUSE_ENTER" value="2" enum="">
+ </constant>
+ <constant name="NOTIFICATION_WM_MOUSE_EXIT" value="3" enum="">
+ </constant>
+ <constant name="NOTIFICATION_WM_FOCUS_IN" value="4" enum="">
</constant>
- <constant name="NOTIFICATION_WM_MOUSE_EXIT" value="3">
+ <constant name="NOTIFICATION_WM_FOCUS_OUT" value="5" enum="">
</constant>
- <constant name="NOTIFICATION_WM_FOCUS_IN" value="4">
+ <constant name="NOTIFICATION_WM_QUIT_REQUEST" value="6" enum="">
</constant>
- <constant name="NOTIFICATION_WM_FOCUS_OUT" value="5">
+ <constant name="NOTIFICATION_WM_UNFOCUS_REQUEST" value="8" enum="">
</constant>
- <constant name="NOTIFICATION_WM_QUIT_REQUEST" value="6">
+ <constant name="NOTIFICATION_OS_MEMORY_WARNING" value="9" enum="">
</constant>
- <constant name="NOTIFICATION_WM_UNFOCUS_REQUEST" value="8">
+ <constant name="NOTIFICATION_TRANSLATION_CHANGED" value="90" enum="">
</constant>
- <constant name="NOTIFICATION_OS_MEMORY_WARNING" value="9">
+ <constant name="NOTIFICATION_WM_ABOUT" value="91" enum="">
</constant>
</constants>
</class>
@@ -24453,18 +27132,40 @@
<description>
</description>
</method>
+ <method name="get_render_priority" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_next_pass">
+ <return type="void">
+ </return>
<argument index="0" name="next_pass" type="Material">
</argument>
<description>
</description>
</method>
+ <method name="set_render_priority">
+ <return type="void">
+ </return>
+ <argument index="0" name="priority" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="next_pass" type="Material" setter="set_next_pass" getter="get_next_pass" brief="">
</member>
+ <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" brief="">
+ </member>
</members>
<constants>
+ <constant name="RENDER_PRIORITY_MAX" value="127" enum="">
+ </constant>
+ <constant name="RENDER_PRIORITY_MIN" value="-128" enum="">
+ </constant>
</constants>
</class>
<class name="MenuButton" inherits="Button" category="Core">
@@ -24535,7 +27236,7 @@
</description>
</method>
<method name="create_outline" qualifiers="const">
- <return type="ArrayMesh">
+ <return type="Mesh">
</return>
<argument index="0" name="margin" type="float">
</argument>
@@ -24592,21 +27293,23 @@
</description>
<methods>
<method name="clear">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="commit_to_surface">
- <return type="int">
+ <return type="int" enum="Error">
</return>
- <argument index="0" name="mesh" type="Object">
+ <argument index="0" name="mesh" type="ArrayMesh">
</argument>
<description>
</description>
</method>
<method name="create_from_surface">
- <return type="int">
+ <return type="int" enum="Error">
</return>
- <argument index="0" name="mesh" type="Object">
+ <argument index="0" name="mesh" type="ArrayMesh">
</argument>
<argument index="1" name="surface" type="int">
</argument>
@@ -24694,7 +27397,7 @@
</description>
</method>
<method name="get_material" qualifiers="const">
- <return type="Object">
+ <return type="Material">
</return>
<description>
</description>
@@ -24794,6 +27497,8 @@
</description>
</method>
<method name="set_edge_meta">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="meta" type="Variant">
@@ -24802,6 +27507,8 @@
</description>
</method>
<method name="set_face_meta">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="meta" type="Variant">
@@ -24810,12 +27517,16 @@
</description>
</method>
<method name="set_material">
+ <return type="void">
+ </return>
<argument index="0" name="material" type="Material">
</argument>
<description>
</description>
</method>
<method name="set_vertex">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="vertex" type="Vector3">
@@ -24824,6 +27535,8 @@
</description>
</method>
<method name="set_vertex_bones">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="bones" type="PoolIntArray">
@@ -24832,6 +27545,8 @@
</description>
</method>
<method name="set_vertex_color">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="color" type="Color">
@@ -24840,6 +27555,8 @@
</description>
</method>
<method name="set_vertex_meta">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="meta" type="Variant">
@@ -24848,6 +27565,8 @@
</description>
</method>
<method name="set_vertex_normal">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="normal" type="Vector3">
@@ -24856,6 +27575,8 @@
</description>
</method>
<method name="set_vertex_tangent">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="tangent" type="Plane">
@@ -24864,6 +27585,8 @@
</description>
</method>
<method name="set_vertex_uv">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="uv" type="Vector2">
@@ -24872,6 +27595,8 @@
</description>
</method>
<method name="set_vertex_uv2">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="uv2" type="Vector2">
@@ -24880,6 +27605,8 @@
</description>
</method>
<method name="set_vertex_weights">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="weights" type="PoolRealArray">
@@ -24900,14 +27627,20 @@
</description>
<methods>
<method name="create_convex_collision">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="create_debug_tangents">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="create_trimesh_collision">
+ <return type="void">
+ </return>
<description>
This helper creates a [StaticBody] child [Node] using the mesh geometry as collision. It's mainly used for testing.
</description>
@@ -24934,6 +27667,8 @@
</description>
</method>
<method name="set_mesh">
+ <return type="void">
+ </return>
<argument index="0" name="mesh" type="Mesh">
</argument>
<description>
@@ -24941,12 +27676,16 @@
</description>
</method>
<method name="set_skeleton_path">
+ <return type="void">
+ </return>
<argument index="0" name="skeleton_path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_surface_material">
+ <return type="void">
+ </return>
<argument index="0" name="surface" type="int">
</argument>
<argument index="1" name="material" type="Material">
@@ -24973,11 +27712,15 @@
</description>
<methods>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear the library.
</description>
</method>
<method name="create_item">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
@@ -25017,8 +27760,16 @@
<description>
</description>
</method>
- <method name="get_item_shape" qualifiers="const">
- <return type="Shape">
+ <method name="get_item_preview" qualifiers="const">
+ <return type="Texture">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_item_shapes" qualifiers="const">
+ <return type="Array">
</return>
<argument index="0" name="id" type="int">
</argument>
@@ -25033,6 +27784,8 @@
</description>
</method>
<method name="remove_item">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
@@ -25040,6 +27793,8 @@
</description>
</method>
<method name="set_item_mesh">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="mesh" type="Mesh">
@@ -25049,6 +27804,8 @@
</description>
</method>
<method name="set_item_name">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="name" type="String">
@@ -25058,6 +27815,8 @@
</description>
</method>
<method name="set_item_navmesh">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="navmesh" type="NavigationMesh">
@@ -25065,10 +27824,22 @@
<description>
</description>
</method>
- <method name="set_item_shape">
+ <method name="set_item_preview">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
- <argument index="1" name="shape" type="Shape">
+ <argument index="1" name="texture" type="Texture">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_item_shapes">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="shapes" type="Array">
</argument>
<description>
</description>
@@ -25096,7 +27867,7 @@
</description>
</method>
<method name="get_color_format" qualifiers="const">
- <return type="int">
+ <return type="int" enum="MultiMesh.ColorFormat">
</return>
<description>
</description>
@@ -25134,18 +27905,22 @@
</description>
</method>
<method name="get_transform_format" qualifiers="const">
- <return type="int">
+ <return type="int" enum="MultiMesh.TransformFormat">
</return>
<description>
</description>
</method>
<method name="set_color_format">
- <argument index="0" name="format" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="MultiMesh.ColorFormat">
</argument>
<description>
</description>
</method>
<method name="set_instance_color">
+ <return type="void">
+ </return>
<argument index="0" name="instance" type="int">
</argument>
<argument index="1" name="color" type="Color">
@@ -25155,6 +27930,8 @@
</description>
</method>
<method name="set_instance_count">
+ <return type="void">
+ </return>
<argument index="0" name="count" type="int">
</argument>
<description>
@@ -25162,6 +27939,8 @@
</description>
</method>
<method name="set_instance_transform">
+ <return type="void">
+ </return>
<argument index="0" name="instance" type="int">
</argument>
<argument index="1" name="transform" type="Transform">
@@ -25171,6 +27950,8 @@
</description>
</method>
<method name="set_mesh">
+ <return type="void">
+ </return>
<argument index="0" name="mesh" type="Mesh">
</argument>
<description>
@@ -25178,7 +27959,9 @@
</description>
</method>
<method name="set_transform_format">
- <argument index="0" name="format" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="MultiMesh.TransformFormat">
</argument>
<description>
</description>
@@ -25187,7 +27970,7 @@
<members>
<member name="color_array" type="PoolColorArray" setter="_set_color_array" getter="_get_color_array" brief="">
</member>
- <member name="color_format" type="int" setter="set_color_format" getter="get_color_format" brief="">
+ <member name="color_format" type="int" setter="set_color_format" getter="get_color_format" brief="" enum="MultiMesh.ColorFormat">
</member>
<member name="instance_count" type="int" setter="set_instance_count" getter="get_instance_count" brief="">
</member>
@@ -25195,7 +27978,7 @@
</member>
<member name="transform_array" type="PoolVector3Array" setter="_set_transform_array" getter="_get_transform_array" brief="">
</member>
- <member name="transform_format" type="int" setter="set_transform_format" getter="get_transform_format" brief="">
+ <member name="transform_format" type="int" setter="set_transform_format" getter="get_transform_format" brief="" enum="MultiMesh.TransformFormat">
</member>
</members>
<constants>
@@ -25220,17 +28003,19 @@
</description>
<methods>
<method name="get_multimesh" qualifiers="const">
- <return type="Object">
+ <return type="MultiMesh">
</return>
<description>
Return the [MultiMesh] that is used for instancing.
</description>
</method>
<method name="set_multimesh">
- <argument index="0" name="multimesh" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="multimesh" type="MultiMesh">
</argument>
<description>
- Set the [MultiMesh] to be instance.
+ Set the [MultiMesh] to be instanced.
</description>
</method>
</methods>
@@ -25250,18 +28035,22 @@
</description>
<methods>
<method name="lock">
+ <return type="void">
+ </return>
<description>
Lock this [Mutex], blocks until it is unlocked by the current owner.
</description>
</method>
<method name="try_lock">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<description>
Try locking this [Mutex], does not block. Returns [OK] on success else [ERR_BUSY].
</description>
</method>
<method name="unlock">
+ <return type="void">
+ </return>
<description>
Unlock this [Mutex], leaving it to others threads.
</description>
@@ -25270,6 +28059,56 @@
<constants>
</constants>
</class>
+<class name="NativeScript" inherits="Script" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_class_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_library" qualifiers="const">
+ <return type="GDNativeLibrary">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="new" qualifiers="vararg">
+ <return type="Object">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_class_name">
+ <return type="void">
+ </return>
+ <argument index="0" name="class_name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_library">
+ <return type="void">
+ </return>
+ <argument index="0" name="library" type="GDNativeLibrary">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="class_name" type="String" setter="set_class_name" getter="get_class_name" brief="">
+ </member>
+ <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="Navigation" inherits="Spatial" category="Core">
<brief_description>
</brief_description>
@@ -25337,18 +28176,22 @@
</argument>
<argument index="1" name="xform" type="Transform">
</argument>
- <argument index="2" name="owner" type="Object" default="NULL">
+ <argument index="2" name="owner" type="Object" default="null">
</argument>
<description>
</description>
</method>
<method name="navmesh_remove">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
</description>
</method>
<method name="navmesh_set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="xform" type="Transform">
@@ -25357,6 +28200,8 @@
</description>
</method>
<method name="set_up_vector">
+ <return type="void">
+ </return>
<argument index="0" name="up" type="Vector3">
</argument>
<description>
@@ -25411,18 +28256,22 @@
</argument>
<argument index="1" name="xform" type="Transform2D">
</argument>
- <argument index="2" name="owner" type="Object" default="NULL">
+ <argument index="2" name="owner" type="Object" default="null">
</argument>
<description>
</description>
</method>
<method name="navpoly_remove">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
</description>
</method>
<method name="navpoly_set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="xform" type="Transform2D">
@@ -25441,12 +28290,24 @@
</description>
<methods>
<method name="add_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="polygon" type="PoolIntArray">
</argument>
<description>
</description>
</method>
<method name="clear_polygons">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="create_from_mesh">
+ <return type="void">
+ </return>
+ <argument index="0" name="mesh" type="Mesh">
+ </argument>
<description>
</description>
</method>
@@ -25471,6 +28332,8 @@
</description>
</method>
<method name="set_vertices">
+ <return type="void">
+ </return>
<argument index="0" name="vertices" type="PoolVector3Array">
</argument>
<description>
@@ -25493,7 +28356,7 @@
</description>
<methods>
<method name="get_navigation_mesh" qualifiers="const">
- <return type="Object">
+ <return type="NavigationMesh">
</return>
<description>
</description>
@@ -25505,13 +28368,17 @@
</description>
</method>
<method name="set_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_navigation_mesh">
- <argument index="0" name="navmesh" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="navmesh" type="NavigationMesh">
</argument>
<description>
</description>
@@ -25533,12 +28400,16 @@
</description>
<methods>
<method name="add_outline">
+ <return type="void">
+ </return>
<argument index="0" name="outline" type="PoolVector2Array">
</argument>
<description>
</description>
</method>
<method name="add_outline_at_index">
+ <return type="void">
+ </return>
<argument index="0" name="outline" type="PoolVector2Array">
</argument>
<argument index="1" name="index" type="int">
@@ -25547,16 +28418,22 @@
</description>
</method>
<method name="add_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="polygon" type="PoolIntArray">
</argument>
<description>
</description>
</method>
<method name="clear_outlines">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="clear_polygons">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -25595,16 +28472,22 @@
</description>
</method>
<method name="make_polygons_from_outlines">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="remove_outline">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
</description>
</method>
<method name="set_outline">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="outline" type="PoolVector2Array">
@@ -25613,6 +28496,8 @@
</description>
</method>
<method name="set_vertices">
+ <return type="void">
+ </return>
<argument index="0" name="vertices" type="PoolVector2Array">
</argument>
<description>
@@ -25624,7 +28509,7 @@
</member>
<member name="polygons" type="Array" setter="_set_polygons" getter="_get_polygons" brief="">
</member>
- <member name="vertices" type="PoolVector3Array" setter="set_vertices" getter="get_vertices" brief="">
+ <member name="vertices" type="PoolVector2Array" setter="set_vertices" getter="get_vertices" brief="">
</member>
</members>
<constants>
@@ -25649,12 +28534,16 @@
</description>
</method>
<method name="set_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_navigation_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="navpoly" type="NavigationPolygon">
</argument>
<description>
@@ -25679,11 +28568,13 @@
</description>
<methods>
<method name="close_connection">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="create_client">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="ip" type="String">
</argument>
@@ -25697,7 +28588,7 @@
</description>
</method>
<method name="create_server">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="port" type="int">
</argument>
@@ -25711,19 +28602,23 @@
</description>
</method>
<method name="get_compression_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="NetworkedMultiplayerENet.CompressionMode">
</return>
<description>
</description>
</method>
<method name="set_bind_ip">
+ <return type="void">
+ </return>
<argument index="0" name="ip" type="String">
</argument>
<description>
</description>
</method>
<method name="set_compression_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="NetworkedMultiplayerENet.CompressionMode">
</argument>
<description>
</description>
@@ -25749,7 +28644,7 @@
</description>
<methods>
<method name="get_connection_status" qualifiers="const">
- <return type="int">
+ <return type="int" enum="NetworkedMultiplayerPeer.ConnectionStatus">
</return>
<description>
</description>
@@ -25773,23 +28668,31 @@
</description>
</method>
<method name="poll">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set_refuse_new_connections">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_target_peer">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
</description>
</method>
<method name="set_transfer_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="NetworkedMultiplayerPeer.TransferMode">
</argument>
<description>
</description>
@@ -25834,9 +28737,9 @@
</constant>
<constant name="CONNECTION_CONNECTED" value="2">
</constant>
- <constant name="TARGET_PEER_BROADCAST" value="0">
+ <constant name="TARGET_PEER_BROADCAST" value="0" enum="">
</constant>
- <constant name="TARGET_PEER_SERVER" value="1">
+ <constant name="TARGET_PEER_SERVER" value="1" enum="">
</constant>
</constants>
</class>
@@ -26012,14 +28915,8 @@
<description>
</description>
<methods>
- <method name="get_draw_center" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
<method name="get_h_axis_stretch_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="NinePatchRect.AxisStretchMode">
</return>
<description>
</description>
@@ -26027,7 +28924,7 @@
<method name="get_patch_margin" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
</description>
@@ -26039,31 +28936,43 @@
</description>
</method>
<method name="get_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
</method>
<method name="get_v_axis_stretch_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="NinePatchRect.AxisStretchMode">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_draw_center_enabled" qualifiers="const">
+ <return type="bool">
</return>
<description>
</description>
</method>
<method name="set_draw_center">
+ <return type="void">
+ </return>
<argument index="0" name="draw_center" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_h_axis_stretch_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="NinePatchRect.AxisStretchMode">
</argument>
<description>
</description>
</method>
<method name="set_patch_margin">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="value" type="int">
</argument>
@@ -26071,30 +28980,36 @@
</description>
</method>
<method name="set_region_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<description>
</description>
</method>
<method name="set_texture">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_v_axis_stretch_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="NinePatchRect.AxisStretchMode">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="axis_stretch_horizontal" type="int" setter="set_h_axis_stretch_mode" getter="get_h_axis_stretch_mode" brief="">
+ <member name="axis_stretch_horizontal" type="int" setter="set_h_axis_stretch_mode" getter="get_h_axis_stretch_mode" brief="" enum="NinePatchRect.AxisStretchMode">
</member>
- <member name="axis_stretch_vertical" type="int" setter="set_v_axis_stretch_mode" getter="get_v_axis_stretch_mode" brief="">
+ <member name="axis_stretch_vertical" type="int" setter="set_v_axis_stretch_mode" getter="get_v_axis_stretch_mode" brief="" enum="NinePatchRect.AxisStretchMode">
</member>
- <member name="draw_center" type="bool" setter="set_draw_center" getter="get_draw_center" brief="">
+ <member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" brief="">
</member>
<member name="patch_margin_bottom" type="int" setter="set_patch_margin" getter="get_patch_margin" brief="">
</member>
@@ -26142,18 +29057,24 @@
</description>
<methods>
<method name="_enter_tree" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
Called when the node enters the [SceneTree] (e.g. upon instancing, scene changing or after calling [method add_child] in a script). If the node has children, its [method _enter_tree] callback will be called first, and then that of the children.
Corresponds to the NOTIFICATION_ENTER_TREE notification in [method Object._notification].
</description>
</method>
<method name="_exit_tree" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
Called when the node leaves the [SceneTree] (e.g. upon freeing, scene changing or after calling [method remove_child] in a script). If the node has children, its [method _exit_tree] callback will be called last, after all its children have left the tree.
Corresponds to the NOTIFICATION_EXIT_TREE notification in [method Object._notification].
</description>
</method>
<method name="_fixed_process" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<description>
@@ -26163,12 +29084,16 @@
</description>
</method>
<method name="_input" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="_process" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<description>
@@ -26178,24 +29103,32 @@
</description>
</method>
<method name="_ready" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
Called when the node is "ready", i.e. when both the node and its children have entered the scene tree. If the node has children, their [method _ready] callback gets triggered first, and the node will receive the ready notification only afterwards.
Corresponds to the NOTIFICATION_READY notification in [method Object._notification].
</description>
</method>
<method name="_unhandled_input" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="_unhandled_key_input" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="event" type="InputEventKey">
</argument>
<description>
</description>
</method>
<method name="add_child">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Node">
</argument>
<argument index="1" name="legible_unique_name" type="bool" default="false">
@@ -26206,6 +29139,8 @@
</description>
</method>
<method name="add_to_group">
+ <return type="void">
+ </return>
<argument index="0" name="group" type="String">
</argument>
<argument index="1" name="persistent" type="bool" default="false">
@@ -26375,7 +29310,7 @@
</description>
</method>
<method name="get_pause_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Node.PauseMode">
</return>
<description>
</description>
@@ -26406,7 +29341,7 @@
</description>
</method>
<method name="get_viewport" qualifiers="const">
- <return type="Object">
+ <return type="Viewport">
</return>
<description>
</description>
@@ -26518,6 +29453,8 @@
</description>
</method>
<method name="move_child">
+ <return type="void">
+ </return>
<argument index="0" name="child_node" type="Node">
</argument>
<argument index="1" name="to_pos" type="int">
@@ -26527,25 +29464,24 @@
</description>
</method>
<method name="print_stray_nodes">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="print_tree">
+ <return type="void">
+ </return>
<description>
Print the scene to stdout. Used mainly for debugging purposes.
</description>
</method>
- <method name="propagate_notification">
- <argument index="0" name="what" type="int">
- </argument>
- <description>
- Notify the current node and all its children recursively by calling notification() in all of them.
- </description>
- </method>
<method name="propagate_call">
+ <return type="void">
+ </return>
<argument index="0" name="method" type="String">
</argument>
- <argument index="1" name="args" type="Array" default="[]">
+ <argument index="1" name="args" type="Array" default="[ ]">
</argument>
<argument index="2" name="parent_first" type="bool" default="false">
</argument>
@@ -26553,21 +29489,38 @@
Calls the method (if present) with the arguments given in "args" on this Node and recursively on all children. If the parent_first argument is true then the method will be called on the current [Node] first, then on all children. If it is false then the children will get called first.
</description>
</method>
+ <method name="propagate_notification">
+ <return type="void">
+ </return>
+ <argument index="0" name="what" type="int">
+ </argument>
+ <description>
+ Notify the current node and all its children recursively by calling notification() in all of them.
+ </description>
+ </method>
<method name="queue_free">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="raise">
+ <return type="void">
+ </return>
<description>
Move this node to the top of the array of nodes of the parent node. This is often useful on GUIs ([Control]), because their order of drawing fully depends on their order in the tree.
</description>
</method>
<method name="remove_and_skip">
+ <return type="void">
+ </return>
<description>
Remove a node and set all its children as children of the parent node (if exists). All even subscriptions that pass by the removed node will be unsubscribed.
</description>
</method>
<method name="remove_child">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Node">
</argument>
<description>
@@ -26575,6 +29528,8 @@
</description>
</method>
<method name="remove_from_group">
+ <return type="void">
+ </return>
<argument index="0" name="group" type="String">
</argument>
<description>
@@ -26582,6 +29537,8 @@
</description>
</method>
<method name="replace_by">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Node">
</argument>
<argument index="1" name="keep_data" type="bool" default="false">
@@ -26591,10 +29548,14 @@
</description>
</method>
<method name="request_ready">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="rpc" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="method" type="String">
</argument>
<description>
@@ -26602,15 +29563,19 @@
</description>
</method>
<method name="rpc_config">
+ <return type="void">
+ </return>
<argument index="0" name="method" type="String">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Node.RPCMode">
</argument>
<description>
Change the method's RPC mode (one of RPC_MODE_* constants).
</description>
</method>
<method name="rpc_id" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="peer_id" type="int">
</argument>
<argument index="1" name="method" type="String">
@@ -26620,6 +29585,8 @@
</description>
</method>
<method name="rpc_unreliable" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="method" type="String">
</argument>
<description>
@@ -26627,6 +29594,8 @@
</description>
</method>
<method name="rpc_unreliable_id" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="peer_id" type="int">
</argument>
<argument index="1" name="method" type="String">
@@ -26636,6 +29605,8 @@
</description>
</method>
<method name="rset">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<argument index="1" name="value" type="Variant">
@@ -26645,15 +29616,19 @@
</description>
</method>
<method name="rset_config">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Node.RPCMode">
</argument>
<description>
Change the property's RPC mode (one of RPC_MODE_* constants).
</description>
</method>
<method name="rset_id">
+ <return type="void">
+ </return>
<argument index="0" name="peer_id" type="int">
</argument>
<argument index="1" name="property" type="String">
@@ -26665,6 +29640,8 @@
</description>
</method>
<method name="rset_unreliable">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<argument index="1" name="value" type="Variant">
@@ -26674,6 +29651,8 @@
</description>
</method>
<method name="rset_unreliable_id">
+ <return type="void">
+ </return>
<argument index="0" name="peer_id" type="int">
</argument>
<argument index="1" name="property" type="String">
@@ -26685,12 +29664,16 @@
</description>
</method>
<method name="set_display_folded">
+ <return type="void">
+ </return>
<argument index="0" name="fold" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_filename">
+ <return type="void">
+ </return>
<argument index="0" name="filename" type="String">
</argument>
<description>
@@ -26698,6 +29681,8 @@
</description>
</method>
<method name="set_fixed_process">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -26705,12 +29690,16 @@
</description>
</method>
<method name="set_fixed_process_internal">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_name">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -26718,6 +29707,8 @@
</description>
</method>
<method name="set_network_master">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="recursive" type="bool" default="true">
@@ -26726,6 +29717,8 @@
</description>
</method>
<method name="set_owner">
+ <return type="void">
+ </return>
<argument index="0" name="owner" type="Node">
</argument>
<description>
@@ -26733,12 +29726,16 @@
</description>
</method>
<method name="set_pause_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Node.PauseMode">
</argument>
<description>
</description>
</method>
<method name="set_process">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -26746,6 +29743,8 @@
</description>
</method>
<method name="set_process_input">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -26753,12 +29752,16 @@
</description>
</method>
<method name="set_process_internal">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_process_unhandled_input">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -26766,12 +29769,16 @@
</description>
</method>
<method name="set_process_unhandled_key_input">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_scene_instance_load_placeholder">
+ <return type="void">
+ </return>
<argument index="0" name="load_placeholder" type="bool">
</argument>
<description>
@@ -26783,7 +29790,7 @@
</member>
<member name="editor/display_folded" type="bool" setter="set_display_folded" getter="is_displayed_folded" brief="">
</member>
- <member name="pause_mode" type="int" setter="set_pause_mode" getter="get_pause_mode" brief="">
+ <member name="pause_mode" type="int" setter="set_pause_mode" getter="get_pause_mode" brief="" enum="Node.PauseMode">
</member>
</members>
<signals>
@@ -26802,42 +29809,42 @@
</signal>
</signals>
<constants>
- <constant name="NOTIFICATION_ENTER_TREE" value="10">
+ <constant name="NOTIFICATION_ENTER_TREE" value="10" enum="">
</constant>
- <constant name="NOTIFICATION_EXIT_TREE" value="11">
+ <constant name="NOTIFICATION_EXIT_TREE" value="11" enum="">
</constant>
- <constant name="NOTIFICATION_MOVED_IN_PARENT" value="12">
+ <constant name="NOTIFICATION_MOVED_IN_PARENT" value="12" enum="">
</constant>
- <constant name="NOTIFICATION_READY" value="13">
+ <constant name="NOTIFICATION_READY" value="13" enum="">
</constant>
- <constant name="NOTIFICATION_FIXED_PROCESS" value="16">
+ <constant name="NOTIFICATION_FIXED_PROCESS" value="16" enum="">
</constant>
- <constant name="NOTIFICATION_PROCESS" value="17">
+ <constant name="NOTIFICATION_PROCESS" value="17" enum="">
Notification received every frame when the process flag is set (see [method set_process]).
</constant>
- <constant name="NOTIFICATION_PARENTED" value="18">
+ <constant name="NOTIFICATION_PARENTED" value="18" enum="">
Notification received when a node is set as a child of another node. Note that this doesn't mean that a node entered the Scene Tree.
</constant>
- <constant name="NOTIFICATION_UNPARENTED" value="19">
+ <constant name="NOTIFICATION_UNPARENTED" value="19" enum="">
Notification received when a node is unparented (parent removed it from the list of children).
</constant>
- <constant name="NOTIFICATION_PAUSED" value="14">
+ <constant name="NOTIFICATION_PAUSED" value="14" enum="">
</constant>
- <constant name="NOTIFICATION_UNPAUSED" value="15">
+ <constant name="NOTIFICATION_UNPAUSED" value="15" enum="">
</constant>
- <constant name="NOTIFICATION_INSTANCED" value="20">
+ <constant name="NOTIFICATION_INSTANCED" value="20" enum="">
</constant>
- <constant name="NOTIFICATION_DRAG_BEGIN" value="21">
+ <constant name="NOTIFICATION_DRAG_BEGIN" value="21" enum="">
</constant>
- <constant name="NOTIFICATION_DRAG_END" value="22">
+ <constant name="NOTIFICATION_DRAG_END" value="22" enum="">
</constant>
- <constant name="NOTIFICATION_PATH_CHANGED" value="23">
+ <constant name="NOTIFICATION_PATH_CHANGED" value="23" enum="">
</constant>
- <constant name="NOTIFICATION_TRANSLATION_CHANGED" value="24">
+ <constant name="NOTIFICATION_TRANSLATION_CHANGED" value="24" enum="">
</constant>
- <constant name="NOTIFICATION_INTERNAL_PROCESS" value="25">
+ <constant name="NOTIFICATION_INTERNAL_PROCESS" value="25" enum="">
</constant>
- <constant name="NOTIFICATION_INTERNAL_FIXED_PROCESS" value="26">
+ <constant name="NOTIFICATION_INTERNAL_FIXED_PROCESS" value="26" enum="">
</constant>
<constant name="RPC_MODE_DISABLED" value="0">
</constant>
@@ -26873,7 +29880,18 @@
Base node for 2D system. Node2D contains a position, rotation and scale, which is used to position and animate. It can alternatively be used with a custom 2D transform ([Transform2D]). A tree of Node2Ds allows complex hierarchies for animation and positioning.
</description>
<methods>
+ <method name="apply_scale">
+ <return type="void">
+ </return>
+ <argument index="0" name="ratio" type="Vector2">
+ </argument>
+ <description>
+ Apply the 'ratio' scale to the 2D node, according to its current scale value.
+ </description>
+ </method>
<method name="edit_set_pivot">
+ <return type="void">
+ </return>
<argument index="0" name="pivot" type="Vector2">
</argument>
<description>
@@ -26927,7 +29945,7 @@
<method name="get_relative_transform_to_parent" qualifiers="const">
<return type="Transform2D">
</return>
- <argument index="0" name="parent" type="Object">
+ <argument index="0" name="parent" type="Node">
</argument>
<description>
Return the transform [Transform2D] calculated relatively to the parent of this 2D node.
@@ -26962,6 +29980,8 @@
</description>
</method>
<method name="global_translate">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -26976,6 +29996,8 @@
</description>
</method>
<method name="look_at">
+ <return type="void">
+ </return>
<argument index="0" name="point" type="Vector2">
</argument>
<description>
@@ -26983,6 +30005,8 @@
</description>
</method>
<method name="move_local_x">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<argument index="1" name="scaled" type="bool" default="false">
@@ -26992,6 +30016,8 @@
</description>
</method>
<method name="move_local_y">
+ <return type="void">
+ </return>
<argument index="0" name="delta" type="float">
</argument>
<argument index="1" name="scaled" type="bool" default="false">
@@ -27001,20 +30027,17 @@
</description>
</method>
<method name="rotate">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
Apply a rotation (in radians) to the 2D node, starting from its current rotation.
</description>
</method>
- <method name="scale">
- <argument index="0" name="ratio" type="Vector2">
- </argument>
- <description>
- Apply the 'ratio' scale to the 2D node, according to its current scale value.
- </description>
- </method>
<method name="set_global_position">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
@@ -27022,6 +30045,8 @@
</description>
</method>
<method name="set_global_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
@@ -27029,6 +30054,8 @@
</description>
</method>
<method name="set_global_rotation_in_degrees">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
@@ -27036,6 +30063,8 @@
</description>
</method>
<method name="set_global_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector2">
</argument>
<description>
@@ -27043,6 +30072,8 @@
</description>
</method>
<method name="set_global_transform">
+ <return type="void">
+ </return>
<argument index="0" name="xform" type="Transform2D">
</argument>
<description>
@@ -27050,6 +30081,8 @@
</description>
</method>
<method name="set_position">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
@@ -27057,6 +30090,8 @@
</description>
</method>
<method name="set_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
@@ -27064,6 +30099,8 @@
</description>
</method>
<method name="set_rotation_in_degrees">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
@@ -27071,6 +30108,8 @@
</description>
</method>
<method name="set_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector2">
</argument>
<description>
@@ -27078,6 +30117,8 @@
</description>
</method>
<method name="set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="xform" type="Transform2D">
</argument>
<description>
@@ -27085,6 +30126,8 @@
</description>
</method>
<method name="set_z">
+ <return type="void">
+ </return>
<argument index="0" name="z" type="int">
</argument>
<description>
@@ -27092,13 +30135,33 @@
</description>
</method>
<method name="set_z_as_relative">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
Set the Z-index value as relative to the parent node of this 2D node. Thus, if this 2D node's Z-index value is 2 and its parent's effective Z-index is 3, then the effective Z-index value of this 2D node would be 3 + 2 = 5.
</description>
</method>
+ <method name="to_global" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="local_point" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="to_local" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="global_point" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="translate">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -27107,13 +30170,13 @@
</method>
</methods>
<members>
- <member name="global_position" type="float" setter="set_global_position" getter="get_global_position" brief="">
+ <member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position" brief="">
</member>
<member name="global_rotation" type="float" setter="set_global_rotation" getter="get_global_rotation" brief="">
</member>
<member name="global_rotation_deg" type="float" setter="set_global_rotation_in_degrees" getter="get_global_rotation_in_degrees" brief="">
</member>
- <member name="global_scale" type="float" setter="set_global_scale" getter="get_global_scale" brief="">
+ <member name="global_scale" type="Vector2" setter="set_global_scale" getter="get_global_scale" brief="">
</member>
<member name="global_transform" type="Transform2D" setter="set_global_transform" getter="get_global_transform" brief="">
</member>
@@ -27220,6 +30283,8 @@
</description>
<methods>
<method name="alert">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<argument index="1" name="title" type="String" default="&quot;Alert!&quot;">
@@ -27243,6 +30308,8 @@
</description>
</method>
<method name="delay_msec" qualifiers="const">
+ <return type="void">
+ </return>
<argument index="0" name="msec" type="int">
</argument>
<description>
@@ -27250,6 +30317,8 @@
</description>
</method>
<method name="delay_usec" qualifiers="const">
+ <return type="void">
+ </return>
<argument index="0" name="usec" type="int">
</argument>
<description>
@@ -27257,6 +30326,8 @@
</description>
</method>
<method name="dump_memory_to_file">
+ <return type="void">
+ </return>
<argument index="0" name="file" type="String">
</argument>
<description>
@@ -27265,6 +30336,8 @@
</description>
</method>
<method name="dump_resources_to_file">
+ <return type="void">
+ </return>
<argument index="0" name="file" type="String">
</argument>
<description>
@@ -27282,7 +30355,7 @@
</argument>
<argument index="2" name="blocking" type="bool">
</argument>
- <argument index="3" name="output" type="Array" default="[]">
+ <argument index="3" name="output" type="Array" default="[ ]">
</argument>
<description>
Execute the binary file in given path, optionally blocking until it returns. A process ID is returned.
@@ -27431,7 +30504,7 @@
</description>
</method>
<method name="get_power_state">
- <return type="int">
+ <return type="int" enum="PowerState">
</return>
<description>
</description>
@@ -27469,7 +30542,7 @@
<method name="get_screen_dpi" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="screen" type="int" default="0">
+ <argument index="0" name="screen" type="int" default="-1">
</argument>
<description>
Returns the dots per inch density of the specified screen.
@@ -27484,7 +30557,7 @@
</description>
</method>
<method name="get_screen_orientation" qualifiers="const">
- <return type="int">
+ <return type="int" enum="_OS.ScreenOrientation">
</return>
<description>
Returns the current screen orientation, the return value will be one of the SCREEN_ORIENTATION constants in this class.
@@ -27493,7 +30566,7 @@
<method name="get_screen_position" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="screen" type="int" default="0">
+ <argument index="0" name="screen" type="int" default="-1">
</argument>
<description>
</description>
@@ -27501,7 +30574,7 @@
<method name="get_screen_size" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="screen" type="int" default="0">
+ <argument index="0" name="screen" type="int" default="-1">
</argument>
<description>
Returns the dimensions in pixels of the specified screen.
@@ -27529,7 +30602,7 @@
<method name="get_system_dir" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="dir" type="int">
+ <argument index="0" name="dir" type="int" enum="_OS.SystemDir">
</argument>
<description>
</description>
@@ -27623,6 +30696,8 @@
</description>
</method>
<method name="hide_virtual_keyboard">
+ <return type="void">
+ </return>
<description>
Hides the virtual keyboard if it is shown, does nothing otherwise.
</description>
@@ -27703,7 +30778,7 @@
</description>
</method>
<method name="kill">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="pid" type="int">
</argument>
@@ -27718,11 +30793,13 @@
</description>
</method>
<method name="native_video_pause">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="native_video_play">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -27736,47 +30813,65 @@
</description>
</method>
<method name="native_video_stop">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="native_video_unpause">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="print_all_resources">
+ <return type="void">
+ </return>
<argument index="0" name="tofile" type="String" default="&quot;&quot;">
</argument>
<description>
</description>
</method>
<method name="print_all_textures_by_size">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="print_resources_by_type">
+ <return type="void">
+ </return>
<argument index="0" name="types" type="PoolStringArray">
</argument>
<description>
</description>
</method>
<method name="print_resources_in_use">
+ <return type="void">
+ </return>
<argument index="0" name="short" type="bool" default="false">
</argument>
<description>
</description>
</method>
<method name="request_attention">
+ <return type="void">
+ </return>
<description>
Request the user attention to the window. It'll flash the taskbar button on Windows or bounce the dock icon on OSX.
</description>
</method>
<method name="set_borderless_window">
+ <return type="void">
+ </return>
<argument index="0" name="borderless" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_clipboard">
+ <return type="void">
+ </return>
<argument index="0" name="clipboard" type="String">
</argument>
<description>
@@ -27784,30 +30879,40 @@
</description>
</method>
<method name="set_current_screen">
+ <return type="void">
+ </return>
<argument index="0" name="screen" type="int">
</argument>
<description>
</description>
</method>
<method name="set_exit_code">
+ <return type="void">
+ </return>
<argument index="0" name="code" type="int">
</argument>
<description>
</description>
</method>
<method name="set_icon">
- <argument index="0" name="icon" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="icon" type="Image">
</argument>
<description>
</description>
</method>
<method name="set_ime_position">
- <argument index="0" name="arg0" type="Vector2">
+ <return type="void">
+ </return>
+ <argument index="0" name="position" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_keep_screen_on">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -27815,6 +30920,8 @@
</description>
</method>
<method name="set_low_processor_usage_mode">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -27822,14 +30929,16 @@
</description>
</method>
<method name="set_screen_orientation">
- <argument index="0" name="orientation" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="orientation" type="int" enum="_OS.ScreenOrientation">
</argument>
<description>
Sets the current screen orientation, the argument value must be one of the SCREEN_ORIENTATION constants in this class.
</description>
</method>
<method name="set_thread_name">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="name" type="String">
</argument>
@@ -27837,18 +30946,24 @@
</description>
</method>
<method name="set_use_file_access_save_and_swap">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_use_vsync">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_window_fullscreen">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -27856,6 +30971,8 @@
</description>
</method>
<method name="set_window_maximized">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -27863,6 +30980,8 @@
</description>
</method>
<method name="set_window_minimized">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -27870,6 +30989,8 @@
</description>
</method>
<method name="set_window_position">
+ <return type="void">
+ </return>
<argument index="0" name="position" type="Vector2">
</argument>
<description>
@@ -27877,6 +30998,8 @@
</description>
</method>
<method name="set_window_resizable">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -27884,6 +31007,8 @@
</description>
</method>
<method name="set_window_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
@@ -27891,6 +31016,8 @@
</description>
</method>
<method name="set_window_title">
+ <return type="void">
+ </return>
<argument index="0" name="title" type="String">
</argument>
<description>
@@ -27898,7 +31025,7 @@
</description>
</method>
<method name="shell_open">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="uri" type="String">
</argument>
@@ -27906,6 +31033,8 @@
</description>
</method>
<method name="show_virtual_keyboard">
+ <return type="void">
+ </return>
<argument index="0" name="existing_text" type="String" default="&quot;&quot;">
</argument>
<description>
@@ -28007,6 +31136,8 @@
</description>
<methods>
<method name="_get" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<description>
@@ -28021,10 +31152,14 @@
</description>
</method>
<method name="_init" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="_notification" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="what" type="int">
</argument>
<description>
@@ -28032,6 +31167,8 @@
</description>
</method>
<method name="_set" qualifiers="virtual">
+ <return type="bool">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<argument index="1" name="value" type="Variant">
@@ -28041,9 +31178,11 @@
</description>
</method>
<method name="add_user_signal">
+ <return type="void">
+ </return>
<argument index="0" name="signal" type="String">
</argument>
- <argument index="1" name="arguments" type="Array" default="[]">
+ <argument index="1" name="arguments" type="Array" default="[ ]">
</argument>
<description>
Add a user signal (can be added anytime). Arguments are optional, but can be added as an array of dictionaries, each containing "name" and "type" (from [@Global Scope] TYPE_*).
@@ -28058,6 +31197,8 @@
</description>
</method>
<method name="call_deferred" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="method" type="String">
</argument>
<description>
@@ -28081,7 +31222,7 @@
</description>
</method>
<method name="connect">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="signal" type="String">
</argument>
@@ -28089,7 +31230,7 @@
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="binds" type="Array" default="[]">
+ <argument index="3" name="binds" type="Array" default="[ ]">
</argument>
<argument index="4" name="flags" type="int" default="0">
</argument>
@@ -28098,6 +31239,8 @@
</description>
</method>
<method name="disconnect">
+ <return type="void">
+ </return>
<argument index="0" name="signal" type="String">
</argument>
<argument index="1" name="target" type="Object">
@@ -28109,12 +31252,16 @@
</description>
</method>
<method name="emit_signal" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="signal" type="String">
</argument>
<description>
</description>
</method>
<method name="free">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -28182,7 +31329,7 @@
</description>
</method>
<method name="get_script" qualifiers="const">
- <return type="Script">
+ <return type="Reference">
</return>
<description>
Return the object script (or null if it doesn't have one).
@@ -28264,6 +31411,8 @@
</description>
</method>
<method name="notification">
+ <return type="void">
+ </return>
<argument index="0" name="what" type="int">
</argument>
<argument index="1" name="reversed" type="bool" default="false">
@@ -28273,10 +31422,14 @@
</description>
</method>
<method name="property_list_changed_notify">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<argument index="1" name="value" type="Variant">
@@ -28286,6 +31439,8 @@
</description>
</method>
<method name="set_block_signals">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -28293,6 +31448,8 @@
</description>
</method>
<method name="set_message_translation">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -28300,6 +31457,8 @@
</description>
</method>
<method name="set_meta">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="value" type="Variant">
@@ -28309,7 +31468,9 @@
</description>
</method>
<method name="set_script">
- <argument index="0" name="script" type="Script">
+ <return type="void">
+ </return>
+ <argument index="0" name="script" type="Reference">
</argument>
<description>
Set a script into the object, scripts extend the object functionality.
@@ -28332,10 +31493,10 @@
</signal>
</signals>
<constants>
- <constant name="NOTIFICATION_POSTINITIALIZE" value="0">
+ <constant name="NOTIFICATION_POSTINITIALIZE" value="0" enum="">
Called right when the object is initialized. Not available in script.
</constant>
- <constant name="NOTIFICATION_PREDELETE" value="1">
+ <constant name="NOTIFICATION_PREDELETE" value="1" enum="">
Called before the object is about to be deleted.
</constant>
<constant name="CONNECT_DEFERRED" value="1">
@@ -28356,7 +31517,7 @@
</description>
<methods>
<method name="get_cull_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="OccluderPolygon2D.CullMode">
</return>
<description>
</description>
@@ -28374,18 +31535,24 @@
</description>
</method>
<method name="set_closed">
+ <return type="void">
+ </return>
<argument index="0" name="closed" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_cull_mode">
- <argument index="0" name="cull_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="cull_mode" type="int" enum="OccluderPolygon2D.CullMode">
</argument>
<description>
</description>
</method>
<method name="set_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="polygon" type="PoolVector2Array">
</argument>
<description>
@@ -28395,7 +31562,7 @@
<members>
<member name="closed" type="bool" setter="set_closed" getter="is_closed" brief="">
</member>
- <member name="cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" brief="">
+ <member name="cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" brief="" enum="OccluderPolygon2D.CullMode">
</member>
<member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon" brief="">
</member>
@@ -28418,25 +31585,29 @@
</description>
<methods>
<method name="get_shadow_detail" qualifiers="const">
- <return type="int">
+ <return type="int" enum="OmniLight.ShadowDetail">
</return>
<description>
</description>
</method>
<method name="get_shadow_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="OmniLight.ShadowMode">
</return>
<description>
</description>
</method>
<method name="set_shadow_detail">
- <argument index="0" name="detail" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="detail" type="int" enum="OmniLight.ShadowDetail">
</argument>
<description>
</description>
</method>
<method name="set_shadow_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="OmniLight.ShadowMode">
</argument>
<description>
</description>
@@ -28447,9 +31618,9 @@
</member>
<member name="omni_range" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="omni_shadow_detail" type="int" setter="set_shadow_detail" getter="get_shadow_detail" brief="">
+ <member name="omni_shadow_detail" type="int" setter="set_shadow_detail" getter="get_shadow_detail" brief="" enum="OmniLight.ShadowDetail">
</member>
- <member name="omni_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" brief="">
+ <member name="omni_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" brief="" enum="OmniLight.ShadowMode">
</member>
</members>
<constants>
@@ -28464,6 +31635,8 @@
</description>
<methods>
<method name="add_icon_item">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="label" type="String">
@@ -28475,6 +31648,8 @@
</description>
</method>
<method name="add_item">
+ <return type="void">
+ </return>
<argument index="0" name="label" type="String">
</argument>
<argument index="1" name="id" type="int" default="-1">
@@ -28484,22 +31659,17 @@
</description>
</method>
<method name="add_separator">
+ <return type="void">
+ </return>
<description>
Add a separator to the list of items. Separators help to group items. Separator also takes up an index and is appended at the end.
</description>
</method>
<method name="clear">
- <description>
- Clear all the items in the [OptionButton].
- </description>
- </method>
- <method name="get_item_id" qualifiers="const">
- <return type="int">
+ <return type="void">
</return>
- <argument index="0" name="idx" type="int">
- </argument>
<description>
- Return the ID of the item at index "idx".
+ Clear all the items in the [OptionButton].
</description>
</method>
<method name="get_item_count" qualifiers="const">
@@ -28518,6 +31688,15 @@
Return the icon of the item at index "idx".
</description>
</method>
+ <method name="get_item_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ Return the ID of the item at index "idx".
+ </description>
+ </method>
<method name="get_item_metadata" qualifiers="const">
<return type="Variant">
</return>
@@ -28563,45 +31742,57 @@
</description>
</method>
<method name="remove_item">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
</description>
</method>
<method name="select">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
Select an item by index and make it the current item.
</description>
</method>
- <method name="set_item_id">
+ <method name="set_item_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="id" type="int">
+ <argument index="1" name="disabled" type="bool">
</argument>
<description>
- Set the ID of an item at index "idx".
</description>
</method>
- <method name="set_item_disabled">
+ <method name="set_item_icon">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="disabled" type="bool">
+ <argument index="1" name="texture" type="Texture">
</argument>
<description>
+ Set the icon of an item at index "idx".
</description>
</method>
- <method name="set_item_icon">
+ <method name="set_item_id">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="texture" type="Texture">
+ <argument index="1" name="id" type="int">
</argument>
<description>
- Set the icon of an item at index "idx".
+ Set the ID of an item at index "idx".
</description>
</method>
<method name="set_item_metadata">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="metadata" type="Variant">
@@ -28610,6 +31801,8 @@
</description>
</method>
<method name="set_item_text">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="text" type="String">
@@ -28672,7 +31865,7 @@
</description>
<methods>
<method name="add_file">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="pck_path" type="String">
</argument>
@@ -28682,7 +31875,7 @@
</description>
</method>
<method name="flush">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="verbose" type="bool">
</argument>
@@ -28690,7 +31883,7 @@
</description>
</method>
<method name="pck_start">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="pck_name" type="String">
</argument>
@@ -28712,6 +31905,8 @@
</description>
<methods>
<method name="generate">
+ <return type="void">
+ </return>
<argument index="0" name="from" type="Translation">
</argument>
<description>
@@ -28728,7 +31923,7 @@
</description>
<methods>
<method name="pack">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="value" type="Variant">
</argument>
@@ -28787,13 +31982,13 @@
<method name="instance" qualifiers="const">
<return type="Node">
</return>
- <argument index="0" name="edit_state" type="int" default="0">
+ <argument index="0" name="edit_state" type="int" enum="PackedScene.GenEditState" default="0">
</argument>
<description>
</description>
</method>
<method name="pack">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="Node">
</argument>
@@ -28838,7 +32033,7 @@
</description>
</method>
<method name="get_packet_error" qualifiers="const">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<description>
Return the error state of the last packet received (via [method get_packet] and [method get_var]).
@@ -28851,8 +32046,14 @@
Get a Variant.
</description>
</method>
+ <method name="is_object_decoding_allowed" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="put_packet">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="buffer" type="PoolByteArray">
</argument>
@@ -28861,7 +32062,7 @@
</description>
</method>
<method name="put_var">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="var" type="Variant">
</argument>
@@ -28869,6 +32070,14 @@
Send a Variant as a packet.
</description>
</method>
+ <method name="set_allow_object_decoding">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
</constants>
@@ -28881,11 +32090,41 @@
PacketStreamPeer provides a wrapper for working using packets over a stream. This allows for using packet based code with StreamPeers. PacketPeerStream implements a custom protocol over the StreamPeer, so the user should not read or write to the wrapped StreamPeer directly.
</description>
<methods>
+ <method name="get_input_buffer_max_size" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_output_buffer_max_size" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_input_buffer_max_size">
+ <return type="void">
+ </return>
+ <argument index="0" name="max_size_bytes" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_output_buffer_max_size">
+ <return type="void">
+ </return>
+ <argument index="0" name="max_size_bytes" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_stream_peer">
- <argument index="0" name="peer" type="StreamPeer">
+ <return type="void">
+ </return>
+ <argument index="0" name="peer" type="Reference">
</argument>
<description>
- Set the StreamPeer object to be wrapped
+ Set the [StreamPeer] object to be wrapped.
</description>
</method>
</methods>
@@ -28901,6 +32140,8 @@
</description>
<methods>
<method name="close">
+ <return type="void">
+ </return>
<description>
Close the UDP socket the [PacketPeerUDP] is currently listening on.
</description>
@@ -28927,7 +32168,7 @@
</description>
</method>
<method name="listen">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="port" type="int">
</argument>
@@ -28943,7 +32184,7 @@
</description>
</method>
<method name="set_dest_address">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="host" type="String">
</argument>
@@ -28954,7 +32195,7 @@
</description>
</method>
<method name="wait">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<description>
Wait for a packet to arrive on the listening port, see [method listen].
@@ -29013,6 +32254,8 @@
</description>
</method>
<method name="set_panorama">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
@@ -29076,6 +32319,8 @@
</description>
</method>
<method name="set_ignore_camera_zoom">
+ <return type="void">
+ </return>
<argument index="0" name="ignore" type="bool">
</argument>
<description>
@@ -29083,6 +32328,8 @@
</description>
</method>
<method name="set_limit_begin">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="Vector2">
</argument>
<description>
@@ -29090,6 +32337,8 @@
</description>
</method>
<method name="set_limit_end">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="Vector2">
</argument>
<description>
@@ -29097,6 +32346,8 @@
</description>
</method>
<method name="set_scroll_base_offset">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="Vector2">
</argument>
<description>
@@ -29104,6 +32355,8 @@
</description>
</method>
<method name="set_scroll_base_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector2">
</argument>
<description>
@@ -29111,6 +32364,8 @@
</description>
</method>
<method name="set_scroll_offset">
+ <return type="void">
+ </return>
<argument index="0" name="ofs" type="Vector2">
</argument>
<description>
@@ -29163,6 +32418,8 @@
</description>
</method>
<method name="set_mirroring">
+ <return type="void">
+ </return>
<argument index="0" name="mirror" type="Vector2">
</argument>
<description>
@@ -29170,12 +32427,16 @@
</description>
</method>
<method name="set_motion_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_motion_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector2">
</argument>
<description>
@@ -29213,7 +32474,7 @@
</description>
</method>
<method name="get_draw_order" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Particles.DrawOrder">
</return>
<description>
</description>
@@ -29305,22 +32566,30 @@
</description>
</method>
<method name="restart">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set_amount">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
</description>
</method>
<method name="set_draw_order">
- <argument index="0" name="order" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="order" type="int" enum="Particles.DrawOrder">
</argument>
<description>
</description>
</method>
<method name="set_draw_pass_mesh">
+ <return type="void">
+ </return>
<argument index="0" name="pass" type="int">
</argument>
<argument index="1" name="mesh" type="Mesh">
@@ -29329,78 +32598,104 @@
</description>
</method>
<method name="set_draw_passes">
+ <return type="void">
+ </return>
<argument index="0" name="passes" type="int">
</argument>
<description>
</description>
</method>
<method name="set_emitting">
+ <return type="void">
+ </return>
<argument index="0" name="emitting" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_explosiveness_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="ratio" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fixed_fps">
+ <return type="void">
+ </return>
<argument index="0" name="fps" type="int">
</argument>
<description>
</description>
</method>
<method name="set_fractional_delta">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_lifetime">
+ <return type="void">
+ </return>
<argument index="0" name="secs" type="float">
</argument>
<description>
</description>
</method>
<method name="set_one_shot">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_pre_process_time">
+ <return type="void">
+ </return>
<argument index="0" name="secs" type="float">
</argument>
<description>
</description>
</method>
<method name="set_process_material">
+ <return type="void">
+ </return>
<argument index="0" name="material" type="Material">
</argument>
<description>
</description>
</method>
<method name="set_randomness_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="ratio" type="float">
</argument>
<description>
</description>
</method>
<method name="set_speed_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="float">
</argument>
<description>
</description>
</method>
<method name="set_use_local_coordinates">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_visibility_aabb">
+ <return type="void">
+ </return>
<argument index="0" name="aabb" type="Rect3">
</argument>
<description>
@@ -29410,7 +32705,7 @@
<members>
<member name="amount" type="int" setter="set_amount" getter="get_amount" brief="">
</member>
- <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" brief="">
+ <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" brief="" enum="Particles.DrawOrder">
</member>
<member name="draw_pass_1" type="Mesh" setter="set_draw_pass_mesh" getter="get_draw_pass_mesh" brief="">
</member>
@@ -29438,7 +32733,7 @@
</member>
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" brief="">
</member>
- <member name="process_material" type="ShaderMaterial,ParticlesMaterial" setter="set_process_material" getter="get_process_material" brief="">
+ <member name="process_material" type="Material" setter="set_process_material" getter="get_process_material" brief="">
</member>
<member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" brief="">
</member>
@@ -29454,7 +32749,7 @@
</constant>
<constant name="DRAW_ORDER_VIEW_DEPTH" value="2">
</constant>
- <constant name="MAX_DRAW_PASSES" value="4">
+ <constant name="MAX_DRAW_PASSES" value="4" enum="">
</constant>
</constants>
</class>
@@ -29480,7 +32775,7 @@
</description>
</method>
<method name="get_draw_order" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Particles2D.DrawOrder">
</return>
<description>
</description>
@@ -29585,10 +32880,14 @@
</description>
</method>
<method name="restart">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set_amount">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -29596,12 +32895,16 @@
</description>
</method>
<method name="set_draw_order">
- <argument index="0" name="order" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="order" type="int" enum="Particles2D.DrawOrder">
</argument>
<description>
</description>
</method>
<method name="set_emitting">
+ <return type="void">
+ </return>
<argument index="0" name="emitting" type="bool">
</argument>
<description>
@@ -29609,30 +32912,40 @@
</description>
</method>
<method name="set_explosiveness_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="ratio" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fixed_fps">
+ <return type="void">
+ </return>
<argument index="0" name="fps" type="int">
</argument>
<description>
</description>
</method>
<method name="set_fractional_delta">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_h_frames">
+ <return type="void">
+ </return>
<argument index="0" name="frames" type="int">
</argument>
<description>
</description>
</method>
<method name="set_lifetime">
+ <return type="void">
+ </return>
<argument index="0" name="secs" type="float">
</argument>
<description>
@@ -29640,60 +32953,80 @@
</description>
</method>
<method name="set_normal_map">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_one_shot">
+ <return type="void">
+ </return>
<argument index="0" name="secs" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_pre_process_time">
+ <return type="void">
+ </return>
<argument index="0" name="secs" type="float">
</argument>
<description>
</description>
</method>
<method name="set_process_material">
+ <return type="void">
+ </return>
<argument index="0" name="material" type="Material">
</argument>
<description>
</description>
</method>
<method name="set_randomness_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="ratio" type="float">
</argument>
<description>
</description>
</method>
<method name="set_speed_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="float">
</argument>
<description>
</description>
</method>
<method name="set_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_use_local_coordinates">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_v_frames">
+ <return type="void">
+ </return>
<argument index="0" name="frames" type="int">
</argument>
<description>
</description>
</method>
<method name="set_visibility_rect">
+ <return type="void">
+ </return>
<argument index="0" name="aabb" type="Rect2">
</argument>
<description>
@@ -29703,7 +33036,7 @@
<members>
<member name="amount" type="int" setter="set_amount" getter="get_amount" brief="">
</member>
- <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" brief="">
+ <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" brief="" enum="Particles2D.DrawOrder">
</member>
<member name="emitting" type="bool" setter="set_emitting" getter="is_emitting" brief="">
</member>
@@ -29725,7 +33058,7 @@
</member>
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" brief="">
</member>
- <member name="process_material" type="ShaderMaterial,ParticlesMaterial" setter="set_process_material" getter="get_process_material" brief="">
+ <member name="process_material" type="Material" setter="set_process_material" getter="get_process_material" brief="">
</member>
<member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" brief="">
</member>
@@ -29735,7 +33068,7 @@
</member>
<member name="v_frames" type="int" setter="set_v_frames" getter="get_v_frames" brief="">
</member>
- <member name="visibility_rect" type="Rect3" setter="set_visibility_rect" getter="get_visibility_rect" brief="">
+ <member name="visibility_rect" type="Rect2" setter="set_visibility_rect" getter="get_visibility_rect" brief="">
</member>
</members>
<constants>
@@ -29794,7 +33127,7 @@
</description>
</method>
<method name="get_emission_shape" qualifiers="const">
- <return type="int">
+ <return type="int" enum="ParticlesMaterial.EmissionShape">
</return>
<description>
</description>
@@ -29808,7 +33141,7 @@
<method name="get_flag" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="flag" type="int">
+ <argument index="0" name="flag" type="int" enum="ParticlesMaterial.Flags">
</argument>
<description>
</description>
@@ -29828,7 +33161,7 @@
<method name="get_param" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter">
</argument>
<description>
</description>
@@ -29836,15 +33169,15 @@
<method name="get_param_randomness" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter">
</argument>
<description>
</description>
</method>
<method name="get_param_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter">
</argument>
<description>
</description>
@@ -29874,61 +33207,81 @@
</description>
</method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_color_ramp">
+ <return type="void">
+ </return>
<argument index="0" name="ramp" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_emission_box_extents">
+ <return type="void">
+ </return>
<argument index="0" name="extents" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_emission_color_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_emission_normal_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_emission_point_count">
+ <return type="void">
+ </return>
<argument index="0" name="point_count" type="int">
</argument>
<description>
</description>
</method>
<method name="set_emission_point_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_emission_shape">
- <argument index="0" name="shape" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="shape" type="int" enum="ParticlesMaterial.EmissionShape">
</argument>
<description>
</description>
</method>
<method name="set_emission_sphere_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
<method name="set_flag">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="ParticlesMaterial.Flags">
</argument>
<argument index="1" name="enable" type="bool">
</argument>
@@ -29936,19 +33289,25 @@
</description>
</method>
<method name="set_flatness">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_gravity">
+ <return type="void">
+ </return>
<argument index="0" name="accel_vec" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_param">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -29956,7 +33315,9 @@
</description>
</method>
<method name="set_param_randomness">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter">
</argument>
<argument index="1" name="randomness" type="float">
</argument>
@@ -29964,32 +33325,42 @@
</description>
</method>
<method name="set_param_texture">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter">
</argument>
- <argument index="1" name="texture" type="Object">
+ <argument index="1" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_spread">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
</description>
</method>
<method name="set_trail_color_modifier">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="GradientTexture">
</argument>
<description>
</description>
</method>
<method name="set_trail_divisor">
+ <return type="void">
+ </return>
<argument index="0" name="divisor" type="int">
</argument>
<description>
</description>
</method>
<method name="set_trail_size_modifier">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="CurveTexture">
</argument>
<description>
@@ -29999,13 +33370,13 @@
<members>
<member name="angle" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="angle_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="angle_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="angle_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
<member name="angular_velocity" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="angular_velocity_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="angular_velocity_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
@@ -30013,23 +33384,23 @@
</member>
<member name="anim_offset" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="anim_offset_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="anim_offset_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="anim_offset_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
<member name="anim_speed" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="anim_speed_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="anim_speed_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="anim_speed_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" brief="">
</member>
- <member name="color_ramp" type="GradientTexture" setter="set_color_ramp" getter="get_color_ramp" brief="">
+ <member name="color_ramp" type="Texture" setter="set_color_ramp" getter="get_color_ramp" brief="">
</member>
<member name="damping" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="damping_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="damping_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="damping_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
@@ -30043,7 +33414,7 @@
</member>
<member name="emission_point_texture" type="Texture" setter="set_emission_point_texture" getter="get_emission_point_texture" brief="">
</member>
- <member name="emission_shape" type="int" setter="set_emission_shape" getter="get_emission_shape" brief="">
+ <member name="emission_shape" type="int" setter="set_emission_shape" getter="get_emission_shape" brief="" enum="ParticlesMaterial.EmissionShape">
</member>
<member name="emission_sphere_radius" type="float" setter="set_emission_sphere_radius" getter="get_emission_sphere_radius" brief="">
</member>
@@ -30059,7 +33430,7 @@
</member>
<member name="hue_variation" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="hue_variation_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="hue_variation_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="hue_variation_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
@@ -30069,25 +33440,25 @@
</member>
<member name="linear_accel" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="linear_accel_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="linear_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="linear_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
<member name="orbit_velocity" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="orbit_velocity_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="orbit_velocity_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
<member name="radial_accel" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="radial_accel_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="radial_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="radial_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
<member name="scale" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="scale_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="scale_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="scale_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
@@ -30095,7 +33466,7 @@
</member>
<member name="tangential_accel" type="float" setter="set_param" getter="get_param" brief="">
</member>
- <member name="tangential_accel_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
+ <member name="tangential_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" brief="">
</member>
<member name="tangential_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
@@ -30167,6 +33538,8 @@
</description>
</method>
<method name="set_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="Curve3D">
</argument>
<description>
@@ -30197,6 +33570,8 @@
</description>
</method>
<method name="set_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="Curve2D">
</argument>
<description>
@@ -30242,7 +33617,7 @@
</description>
</method>
<method name="get_rotation_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="PathFollow.RotationMode">
</return>
<description>
Returns the rotation mode. The constants below list which axes are allowed to rotate for each mode.
@@ -30270,6 +33645,8 @@
</description>
</method>
<method name="set_cubic_interpolation">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -30279,6 +33656,8 @@
</description>
</method>
<method name="set_h_offset">
+ <return type="void">
+ </return>
<argument index="0" name="h_offset" type="float">
</argument>
<description>
@@ -30287,6 +33666,8 @@
</description>
</method>
<method name="set_loop">
+ <return type="void">
+ </return>
<argument index="0" name="loop" type="bool">
</argument>
<description>
@@ -30294,6 +33675,8 @@
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="float">
</argument>
<description>
@@ -30301,13 +33684,17 @@
</description>
</method>
<method name="set_rotation_mode">
- <argument index="0" name="rotation_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="rotation_mode" type="int" enum="PathFollow.RotationMode">
</argument>
<description>
Allows or forbids rotation on one or more axes, per the constants below.
</description>
</method>
<method name="set_unit_offset">
+ <return type="void">
+ </return>
<argument index="0" name="unit_offset" type="float">
</argument>
<description>
@@ -30315,6 +33702,8 @@
</description>
</method>
<method name="set_v_offset">
+ <return type="void">
+ </return>
<argument index="0" name="v_offset" type="float">
</argument>
<description>
@@ -30396,6 +33785,8 @@
</description>
</method>
<method name="set_cubic_interpolation">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -30405,6 +33796,8 @@
</description>
</method>
<method name="set_h_offset">
+ <return type="void">
+ </return>
<argument index="0" name="h_offset" type="float">
</argument>
<description>
@@ -30413,6 +33806,8 @@
</description>
</method>
<method name="set_loop">
+ <return type="void">
+ </return>
<argument index="0" name="loop" type="bool">
</argument>
<description>
@@ -30420,6 +33815,8 @@
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="float">
</argument>
<description>
@@ -30427,6 +33824,8 @@
</description>
</method>
<method name="set_rotate">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -30434,6 +33833,8 @@
</description>
</method>
<method name="set_unit_offset">
+ <return type="void">
+ </return>
<argument index="0" name="unit_offset" type="float">
</argument>
<description>
@@ -30441,6 +33842,8 @@
</description>
</method>
<method name="set_v_offset">
+ <return type="void">
+ </return>
<argument index="0" name="v_offset" type="float">
</argument>
<description>
@@ -30460,7 +33863,7 @@
<method name="get_monitor" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="monitor" type="int">
+ <argument index="0" name="monitor" type="int" enum="Performance.Monitor">
</argument>
<description>
</description>
@@ -30701,6 +34104,8 @@
</description>
</method>
<method name="integrate_forces">
+ <return type="void">
+ </return>
<description>
Call the built-in force integration code.
</description>
@@ -30713,6 +34118,8 @@
</description>
</method>
<method name="set_angular_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="velocity" type="float">
</argument>
<description>
@@ -30720,6 +34127,8 @@
</description>
</method>
<method name="set_linear_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="velocity" type="Vector2">
</argument>
<description>
@@ -30727,6 +34136,8 @@
</description>
</method>
<method name="set_sleep_state">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -30734,6 +34145,8 @@
</description>
</method>
<method name="set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="transform" type="Transform2D">
</argument>
<description>
@@ -30810,7 +34223,7 @@
</argument>
<argument index="1" name="max_results" type="int" default="32">
</argument>
- <argument index="2" name="exclude" type="Array" default="[]">
+ <argument index="2" name="exclude" type="Array" default="[ ]">
</argument>
<argument index="3" name="collision_layer" type="int" default="2147483647">
</argument>
@@ -30833,7 +34246,7 @@
</argument>
<argument index="1" name="to" type="Vector2">
</argument>
- <argument index="2" name="exclude" type="Array" default="[]">
+ <argument index="2" name="exclude" type="Array" default="[ ]">
</argument>
<argument index="3" name="collision_layer" type="int" default="2147483647">
</argument>
@@ -30900,17 +34313,21 @@
</description>
<methods>
<method name="area_add_shape">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape" type="RID">
</argument>
- <argument index="2" name="transform" type="Transform2D" default="((1, 0), (0, 1), (0, 0))">
+ <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )">
</argument>
<description>
Add a shape to the area, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
</description>
</method>
<method name="area_attach_object_instance_id">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="id" type="int">
@@ -30920,6 +34337,8 @@
</description>
</method>
<method name="area_clear_shapes">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<description>
@@ -30943,9 +34362,11 @@
</description>
</method>
<method name="area_get_param" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.AreaParameter">
</argument>
<description>
Return an area parameter value.
@@ -30992,7 +34413,7 @@
</description>
</method>
<method name="area_get_space_override_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Physics2DServer.AreaSpaceOverrideMode">
</return>
<argument index="0" name="area" type="RID">
</argument>
@@ -31010,6 +34431,8 @@
</description>
</method>
<method name="area_remove_shape">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31019,6 +34442,8 @@
</description>
</method>
<method name="area_set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="layer" type="int">
@@ -31028,6 +34453,8 @@
</description>
</method>
<method name="area_set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="mask" type="int">
@@ -31037,6 +34464,8 @@
</description>
</method>
<method name="area_set_monitor_callback">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="receiver" type="Object">
@@ -31053,9 +34482,11 @@
</description>
</method>
<method name="area_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.AreaParameter">
</argument>
<argument index="2" name="value" type="Variant">
</argument>
@@ -31064,6 +34495,8 @@
</description>
</method>
<method name="area_set_shape">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31075,6 +34508,8 @@
</description>
</method>
<method name="area_set_shape_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31085,6 +34520,8 @@
</description>
</method>
<method name="area_set_shape_transform">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31096,6 +34533,8 @@
</description>
</method>
<method name="area_set_space">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="space" type="RID">
@@ -31105,15 +34544,19 @@
</description>
</method>
<method name="area_set_space_override_mode">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Physics2DServer.AreaSpaceOverrideMode">
</argument>
<description>
Set the space override mode for the area. The modes are described in the constants AREA_SPACE_OVERRIDE_*.
</description>
</method>
<method name="area_set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="transform" type="Transform2D">
@@ -31123,6 +34566,8 @@
</description>
</method>
<method name="body_add_collision_exception">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="excepted_body" type="RID">
@@ -31132,6 +34577,8 @@
</description>
</method>
<method name="body_add_force">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="offset" type="Vector2">
@@ -31143,17 +34590,21 @@
</description>
</method>
<method name="body_add_shape">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape" type="RID">
</argument>
- <argument index="2" name="transform" type="Transform2D" default="((1, 0), (0, 1), (0, 0))">
+ <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )">
</argument>
<description>
Add a shape to the body, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
</description>
</method>
<method name="body_apply_impulse">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="pos" type="Vector2">
@@ -31165,6 +34616,8 @@
</description>
</method>
<method name="body_attach_object_instance_id">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="id" type="int">
@@ -31174,6 +34627,8 @@
</description>
</method>
<method name="body_clear_shapes">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<description>
@@ -31183,7 +34638,7 @@
<method name="body_create">
<return type="RID">
</return>
- <argument index="0" name="mode" type="int" default="2">
+ <argument index="0" name="mode" type="int" enum="Physics2DServer.BodyMode" default="2">
</argument>
<argument index="1" name="init_sleeping" type="bool" default="false">
</argument>
@@ -31210,7 +34665,7 @@
</description>
</method>
<method name="body_get_continuous_collision_detection_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Physics2DServer.CCDMode">
</return>
<argument index="0" name="body" type="RID">
</argument>
@@ -31228,7 +34683,7 @@
</description>
</method>
<method name="body_get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Physics2DServer.BodyMode">
</return>
<argument index="0" name="body" type="RID">
</argument>
@@ -31250,7 +34705,7 @@
</return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.BodyParameter">
</argument>
<description>
Return the value of a body parameter.
@@ -31277,6 +34732,8 @@
</description>
</method>
<method name="body_get_shape_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31306,9 +34763,11 @@
</description>
</method>
<method name="body_get_state" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="state" type="int">
+ <argument index="1" name="state" type="int" enum="Physics2DServer.BodyState">
</argument>
<description>
Return a body state.
@@ -31324,6 +34783,8 @@
</description>
</method>
<method name="body_remove_collision_exception">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="excepted_body" type="RID">
@@ -31333,6 +34794,8 @@
</description>
</method>
<method name="body_remove_shape">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31342,6 +34805,8 @@
</description>
</method>
<method name="body_set_axis_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="axis_velocity" type="Vector2">
@@ -31351,6 +34816,8 @@
</description>
</method>
<method name="body_set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="layer" type="int">
@@ -31360,6 +34827,8 @@
</description>
</method>
<method name="body_set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="mask" type="int">
@@ -31369,9 +34838,11 @@
</description>
</method>
<method name="body_set_continuous_collision_detection_mode">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Physics2DServer.CCDMode">
</argument>
<description>
Set the continuous collision detection mode from any of the CCD_MODE_* constants.
@@ -31379,19 +34850,23 @@
</description>
</method>
<method name="body_set_force_integration_callback">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="receiver" type="Object">
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="userdata" type="Variant" default="NULL">
+ <argument index="3" name="userdata" type="Variant" default="null">
</argument>
<description>
Set the function used to calculate physics for an object, if that object allows it (see [method body_set_omit_force integration]).
</description>
</method>
<method name="body_set_max_contacts_reported">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="amount" type="int">
@@ -31401,15 +34876,19 @@
</description>
</method>
<method name="body_set_mode">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="Physics2DServer.BodyMode">
</argument>
<description>
Set the body mode, from one of the constants BODY_MODE*.
</description>
</method>
<method name="body_set_omit_force_integration">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="enable" type="bool">
@@ -31419,9 +34898,11 @@
</description>
</method>
<method name="body_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.BodyParameter">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -31430,6 +34911,8 @@
</description>
</method>
<method name="body_set_shape">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31441,6 +34924,8 @@
</description>
</method>
<method name="body_set_shape_as_one_way_collision">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31451,6 +34936,8 @@
</description>
</method>
<method name="body_set_shape_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31461,6 +34948,8 @@
</description>
</method>
<method name="body_set_shape_metadata">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31472,6 +34961,8 @@
</description>
</method>
<method name="body_set_shape_transform">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -31483,6 +34974,8 @@
</description>
</method>
<method name="body_set_space">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="space" type="RID">
@@ -31492,9 +34985,11 @@
</description>
</method>
<method name="body_set_state">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="state" type="int">
+ <argument index="1" name="state" type="int" enum="Physics2DServer.BodyState">
</argument>
<argument index="2" name="value" type="Variant">
</argument>
@@ -31513,7 +35008,7 @@
</argument>
<argument index="3" name="margin" type="float" default="0.08">
</argument>
- <argument index="4" name="result" type="Physics2DTestMotionResult" default="NULL">
+ <argument index="4" name="result" type="Physics2DTestMotionResult" default="null">
</argument>
<description>
Return whether a body can move from a given point in a given direction. Apart from the boolean return value, a [Physics2DTestMotionResult] can be passed to return additional information in.
@@ -31528,7 +35023,7 @@
</argument>
<argument index="2" name="body_a" type="RID">
</argument>
- <argument index="3" name="body_b" type="RID" default="[RID]">
+ <argument index="3" name="body_b" type="RID">
</argument>
<description>
Create a damped spring joint between two bodies. If not specified, the second body is assumed to be the joint itself.
@@ -31539,16 +35034,18 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.DampedStringParam">
</argument>
<description>
Return the value of a damped spring joint parameter.
</description>
</method>
<method name="damped_string_joint_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.DampedStringParam">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -31557,6 +35054,8 @@
</description>
</method>
<method name="free_rid">
+ <return type="void">
+ </return>
<argument index="0" name="rid" type="RID">
</argument>
<description>
@@ -31566,7 +35065,7 @@
<method name="get_process_info">
<return type="int">
</return>
- <argument index="0" name="process_info" type="int">
+ <argument index="0" name="process_info" type="int" enum="Physics2DServer.ProcessInfo">
</argument>
<description>
Return information about the current state of the 2D physics engine. The states are listed under the INFO_* constants.
@@ -31581,9 +35080,9 @@
</argument>
<argument index="2" name="anchor_b" type="Vector2">
</argument>
- <argument index="3" name="body_a" type="RID" default="[RID]">
+ <argument index="3" name="body_a" type="RID">
</argument>
- <argument index="4" name="body_b" type="RID" default="[RID]">
+ <argument index="4" name="body_b" type="RID">
</argument>
<description>
Create a groove joint between two bodies. If not specified, the bodyies are assumed to be the joint itself.
@@ -31594,14 +35093,14 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.JointParam">
</argument>
<description>
Return the value of a joint parameter.
</description>
</method>
<method name="joint_get_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Physics2DServer.JointType">
</return>
<argument index="0" name="joint" type="RID">
</argument>
@@ -31610,9 +35109,11 @@
</description>
</method>
<method name="joint_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.JointParam">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -31627,13 +35128,15 @@
</argument>
<argument index="1" name="body_a" type="RID">
</argument>
- <argument index="2" name="body_b" type="RID" default="[RID]">
+ <argument index="2" name="body_b" type="RID">
</argument>
<description>
Create a pin joint between two bodies. If not specified, the second body is assumed to be the joint itself.
</description>
</method>
<method name="set_active">
+ <return type="void">
+ </return>
<argument index="0" name="active" type="bool">
</argument>
<description>
@@ -31643,13 +35146,15 @@
<method name="shape_create">
<return type="RID">
</return>
- <argument index="0" name="type" type="int">
+ <argument index="0" name="type" type="int" enum="Physics2DServer.ShapeType">
</argument>
<description>
Create a shape of type SHAPE_*. Does not assign it to a body or an area. To do so, you must use [method area_set_shape] or [method body_set_shape].
</description>
</method>
<method name="shape_get_data" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="shape" type="RID">
</argument>
<description>
@@ -31657,7 +35162,7 @@
</description>
</method>
<method name="shape_get_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Physics2DServer.ShapeType">
</return>
<argument index="0" name="shape" type="RID">
</argument>
@@ -31666,6 +35171,8 @@
</description>
</method>
<method name="shape_set_data">
+ <return type="void">
+ </return>
<argument index="0" name="shape" type="RID">
</argument>
<argument index="1" name="data" type="Variant">
@@ -31695,7 +35202,7 @@
</return>
<argument index="0" name="space" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.SpaceParameter">
</argument>
<description>
Return the value of a space parameter.
@@ -31711,6 +35218,8 @@
</description>
</method>
<method name="space_set_active">
+ <return type="void">
+ </return>
<argument index="0" name="space" type="RID">
</argument>
<argument index="1" name="active" type="bool">
@@ -31720,9 +35229,11 @@
</description>
</method>
<method name="space_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="space" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="Physics2DServer.SpaceParameter">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -31979,6 +35490,8 @@
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="collision_layer" type="int">
</argument>
<description>
@@ -31986,6 +35499,8 @@
</description>
</method>
<method name="set_exclude">
+ <return type="void">
+ </return>
<argument index="0" name="exclude" type="Array">
</argument>
<description>
@@ -31993,6 +35508,8 @@
</description>
</method>
<method name="set_margin">
+ <return type="void">
+ </return>
<argument index="0" name="margin" type="float">
</argument>
<description>
@@ -32000,6 +35517,8 @@
</description>
</method>
<method name="set_motion">
+ <return type="void">
+ </return>
<argument index="0" name="motion" type="Vector2">
</argument>
<description>
@@ -32007,6 +35526,8 @@
</description>
</method>
<method name="set_object_type_mask">
+ <return type="void">
+ </return>
<argument index="0" name="object_type_mask" type="int">
</argument>
<description>
@@ -32014,13 +35535,17 @@
</description>
</method>
<method name="set_shape">
- <argument index="0" name="shape" type="Shape2D">
+ <return type="void">
+ </return>
+ <argument index="0" name="shape" type="Resource">
</argument>
<description>
Set the [Shape2D] that will be used for collision/intersection queries.
</description>
</method>
<method name="set_shape_rid">
+ <return type="void">
+ </return>
<argument index="0" name="shape" type="RID">
</argument>
<description>
@@ -32028,6 +35553,8 @@
</description>
</method>
<method name="set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="transform" type="Transform2D">
</argument>
<description>
@@ -32159,9 +35686,12 @@
</description>
<methods>
<method name="add_collision_exception_with">
- <argument index="0" name="body" type="PhysicsBody">
+ <return type="void">
+ </return>
+ <argument index="0" name="body" type="Node">
</argument>
<description>
+ Adds a body to the collision exception list. This list contains bodies that this body will not collide with.
</description>
</method>
<method name="get_collision_layer" qualifiers="const">
@@ -32193,18 +35723,25 @@
</description>
</method>
<method name="remove_collision_exception_with">
- <argument index="0" name="body" type="PhysicsBody">
+ <return type="void">
+ </return>
+ <argument index="0" name="body" type="Node">
</argument>
<description>
+ Removes a body from the collision exception list.
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
</description>
</method>
<method name="set_collision_layer_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -32213,12 +35750,16 @@
</description>
</method>
<method name="set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_collision_mask_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -32245,10 +35786,11 @@
</description>
<methods>
<method name="add_collision_exception_with">
- <argument index="0" name="body" type="PhysicsBody2D">
+ <return type="void">
+ </return>
+ <argument index="0" name="body" type="Node">
</argument>
<description>
- Adds a body to the collision exception list. This list contains bodies that this body will not collide with.
</description>
</method>
<method name="get_collision_layer" qualifiers="const">
@@ -32284,13 +35826,16 @@
</description>
</method>
<method name="remove_collision_exception_with">
- <argument index="0" name="body" type="PhysicsBody2D">
+ <return type="void">
+ </return>
+ <argument index="0" name="body" type="Node">
</argument>
<description>
- Removes a body from the collision exception list.
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
@@ -32300,6 +35845,8 @@
</description>
</method>
<method name="set_collision_layer_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -32309,6 +35856,8 @@
</description>
</method>
<method name="set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
@@ -32316,6 +35865,8 @@
</description>
</method>
<method name="set_collision_mask_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -32343,6 +35894,8 @@
</description>
<methods>
<method name="add_force">
+ <return type="void">
+ </return>
<argument index="0" name="force" type="Vector3">
</argument>
<argument index="1" name="pos" type="Vector3">
@@ -32351,6 +35904,8 @@
</description>
</method>
<method name="apply_impulse">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector3">
</argument>
<argument index="1" name="j" type="Vector3">
@@ -32359,6 +35914,8 @@
</description>
</method>
<method name="apply_torqe_impulse">
+ <return type="void">
+ </return>
<argument index="0" name="j" type="Vector3">
</argument>
<description>
@@ -32472,7 +36029,7 @@
<description>
</description>
</method>
- <method name="get_principal_inetria_axes" qualifiers="const">
+ <method name="get_principal_inertia_axes" qualifiers="const">
<return type="Basis">
</return>
<description>
@@ -32515,6 +36072,8 @@
</description>
</method>
<method name="integrate_forces">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -32525,24 +36084,32 @@
</description>
</method>
<method name="set_angular_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="velocity" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_linear_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="velocity" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_sleep_state">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="transform" type="Transform">
</argument>
<description>
@@ -32603,7 +36170,7 @@
</argument>
<argument index="1" name="to" type="Vector3">
</argument>
- <argument index="2" name="exclude" type="Array" default="[]">
+ <argument index="2" name="exclude" type="Array" default="[ ]">
</argument>
<argument index="3" name="collision_layer" type="int" default="2147483647">
</argument>
@@ -32645,16 +36212,20 @@
</description>
<methods>
<method name="area_add_shape">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape" type="RID">
</argument>
- <argument index="2" name="transform" type="Transform" default="Transform()">
+ <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
</argument>
<description>
</description>
</method>
<method name="area_attach_object_instance_id">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="id" type="int">
@@ -32663,6 +36234,8 @@
</description>
</method>
<method name="area_clear_shapes">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<description>
@@ -32683,9 +36256,11 @@
</description>
</method>
<method name="area_get_param" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.AreaParameter">
</argument>
<description>
</description>
@@ -32727,7 +36302,7 @@
</description>
</method>
<method name="area_get_space_override_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="PhysicsServer.AreaSpaceOverrideMode">
</return>
<argument index="0" name="area" type="RID">
</argument>
@@ -32751,6 +36326,8 @@
</description>
</method>
<method name="area_remove_shape">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -32759,6 +36336,8 @@
</description>
</method>
<method name="area_set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="layer" type="int">
@@ -32767,6 +36346,8 @@
</description>
</method>
<method name="area_set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="mask" type="int">
@@ -32775,6 +36356,8 @@
</description>
</method>
<method name="area_set_monitor_callback">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="receiver" type="Object">
@@ -32785,9 +36368,11 @@
</description>
</method>
<method name="area_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.AreaParameter">
</argument>
<argument index="2" name="value" type="Variant">
</argument>
@@ -32795,6 +36380,8 @@
</description>
</method>
<method name="area_set_ray_pickable">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="enable" type="bool">
@@ -32803,6 +36390,8 @@
</description>
</method>
<method name="area_set_shape">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -32813,6 +36402,8 @@
</description>
</method>
<method name="area_set_shape_transform">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -32823,6 +36414,8 @@
</description>
</method>
<method name="area_set_space">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="space" type="RID">
@@ -32831,14 +36424,18 @@
</description>
</method>
<method name="area_set_space_override_mode">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="PhysicsServer.AreaSpaceOverrideMode">
</argument>
<description>
</description>
</method>
<method name="area_set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="transform" type="Transform">
@@ -32847,6 +36444,8 @@
</description>
</method>
<method name="body_add_collision_exception">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="excepted_body" type="RID">
@@ -32855,16 +36454,20 @@
</description>
</method>
<method name="body_add_shape">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape" type="RID">
</argument>
- <argument index="2" name="transform" type="Transform" default="Transform()">
+ <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
</argument>
<description>
</description>
</method>
<method name="body_apply_impulse">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="pos" type="Vector3">
@@ -32875,6 +36478,8 @@
</description>
</method>
<method name="body_apply_torque_impulse">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="impulse" type="Vector3">
@@ -32883,6 +36488,8 @@
</description>
</method>
<method name="body_attach_object_instance_id">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="id" type="int">
@@ -32891,6 +36498,8 @@
</description>
</method>
<method name="body_clear_shapes">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<description>
@@ -32899,7 +36508,7 @@
<method name="body_create">
<return type="RID">
</return>
- <argument index="0" name="mode" type="int" default="2">
+ <argument index="0" name="mode" type="int" enum="PhysicsServer.BodyMode" default="2">
</argument>
<argument index="1" name="init_sleeping" type="bool" default="false">
</argument>
@@ -32907,7 +36516,7 @@
</description>
</method>
<method name="body_get_axis_lock" qualifiers="const">
- <return type="int">
+ <return type="int" enum="PhysicsServer.BodyAxisLock">
</return>
<argument index="0" name="body" type="RID">
</argument>
@@ -32939,7 +36548,7 @@
</description>
</method>
<method name="body_get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="PhysicsServer.BodyMode">
</return>
<argument index="0" name="body" type="RID">
</argument>
@@ -32959,7 +36568,7 @@
</return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.BodyParameter">
</argument>
<description>
</description>
@@ -33001,9 +36610,11 @@
</description>
</method>
<method name="body_get_state" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="state" type="int">
+ <argument index="1" name="state" type="int" enum="PhysicsServer.BodyState">
</argument>
<description>
</description>
@@ -33033,6 +36644,8 @@
</description>
</method>
<method name="body_remove_collision_exception">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="excepted_body" type="RID">
@@ -33041,6 +36654,8 @@
</description>
</method>
<method name="body_remove_shape">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -33049,14 +36664,18 @@
</description>
</method>
<method name="body_set_axis_lock">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="axis" type="int">
+ <argument index="1" name="axis" type="int" enum="PhysicsServer.BodyAxisLock">
</argument>
<description>
</description>
</method>
<method name="body_set_axis_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="axis_velocity" type="Vector3">
@@ -33065,6 +36684,8 @@
</description>
</method>
<method name="body_set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="layer" type="int">
@@ -33073,6 +36694,8 @@
</description>
</method>
<method name="body_set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="mask" type="int">
@@ -33081,6 +36704,8 @@
</description>
</method>
<method name="body_set_enable_continuous_collision_detection">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="enable" type="bool">
@@ -33089,18 +36714,22 @@
</description>
</method>
<method name="body_set_force_integration_callback">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="receiver" type="Object">
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="userdata" type="Variant" default="NULL">
+ <argument index="3" name="userdata" type="Variant" default="null">
</argument>
<description>
</description>
</method>
<method name="body_set_max_contacts_reported">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="amount" type="int">
@@ -33109,14 +36738,18 @@
</description>
</method>
<method name="body_set_mode">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="PhysicsServer.BodyMode">
</argument>
<description>
</description>
</method>
<method name="body_set_omit_force_integration">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="enable" type="bool">
@@ -33125,9 +36758,11 @@
</description>
</method>
<method name="body_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.BodyParameter">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -33135,6 +36770,8 @@
</description>
</method>
<method name="body_set_ray_pickable">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="enable" type="bool">
@@ -33143,6 +36780,8 @@
</description>
</method>
<method name="body_set_shape">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -33153,6 +36792,8 @@
</description>
</method>
<method name="body_set_shape_transform">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -33163,6 +36804,8 @@
</description>
</method>
<method name="body_set_space">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="space" type="RID">
@@ -33171,9 +36814,11 @@
</description>
</method>
<method name="body_set_state">
+ <return type="void">
+ </return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="state" type="int">
+ <argument index="1" name="state" type="int" enum="PhysicsServer.BodyState">
</argument>
<argument index="2" name="value" type="Variant">
</argument>
@@ -33185,15 +36830,17 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.ConeTwistJointParam">
</argument>
<description>
</description>
</method>
<method name="cone_twist_joint_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.ConeTwistJointParam">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -33201,6 +36848,8 @@
</description>
</method>
<method name="free_rid">
+ <return type="void">
+ </return>
<argument index="0" name="rid" type="RID">
</argument>
<description>
@@ -33211,9 +36860,9 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="axis" type="int">
+ <argument index="1" name="axis" type="int" enum="Vector3.Axis">
</argument>
- <argument index="2" name="flag" type="int">
+ <argument index="2" name="flag" type="int" enum="PhysicsServer.G6DOFJointAxisFlag">
</argument>
<description>
</description>
@@ -33223,19 +36872,21 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="axis" type="int">
+ <argument index="1" name="axis" type="int" enum="Vector3.Axis">
</argument>
- <argument index="2" name="param" type="int">
+ <argument index="2" name="param" type="int" enum="PhysicsServer.G6DOFJointAxisParam">
</argument>
<description>
</description>
</method>
<method name="generic_6dof_joint_set_flag">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="axis" type="int">
+ <argument index="1" name="axis" type="int" enum="Vector3.Axis">
</argument>
- <argument index="2" name="flag" type="int">
+ <argument index="2" name="flag" type="int" enum="PhysicsServer.G6DOFJointAxisFlag">
</argument>
<argument index="3" name="enable" type="bool">
</argument>
@@ -33243,11 +36894,13 @@
</description>
</method>
<method name="generic_6dof_joint_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="axis" type="int">
+ <argument index="1" name="axis" type="int" enum="Vector3.Axis">
</argument>
- <argument index="2" name="param" type="int">
+ <argument index="2" name="param" type="int" enum="PhysicsServer.G6DOFJointAxisParam">
</argument>
<argument index="3" name="value" type="float">
</argument>
@@ -33257,7 +36910,7 @@
<method name="get_process_info">
<return type="int">
</return>
- <argument index="0" name="process_info" type="int">
+ <argument index="0" name="process_info" type="int" enum="PhysicsServer.ProcessInfo">
</argument>
<description>
</description>
@@ -33267,7 +36920,7 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="flag" type="int">
+ <argument index="1" name="flag" type="int" enum="PhysicsServer.HingeJointFlag">
</argument>
<description>
</description>
@@ -33277,15 +36930,17 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.HingeJointParam">
</argument>
<description>
</description>
</method>
<method name="hinge_joint_set_flag">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="flag" type="int">
+ <argument index="1" name="flag" type="int" enum="PhysicsServer.HingeJointFlag">
</argument>
<argument index="2" name="enabled" type="bool">
</argument>
@@ -33293,9 +36948,11 @@
</description>
</method>
<method name="hinge_joint_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.HingeJointParam">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -33381,7 +37038,7 @@
</description>
</method>
<method name="joint_get_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="PhysicsServer.JointType">
</return>
<argument index="0" name="joint" type="RID">
</argument>
@@ -33389,6 +37046,8 @@
</description>
</method>
<method name="joint_set_solver_priority">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
<argument index="1" name="priority" type="int">
@@ -33417,12 +37076,14 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.PinJointParam">
</argument>
<description>
</description>
</method>
<method name="pin_joint_set_local_a">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
<argument index="1" name="local_A" type="Vector3">
@@ -33431,6 +37092,8 @@
</description>
</method>
<method name="pin_joint_set_local_b">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
<argument index="1" name="local_B" type="Vector3">
@@ -33439,9 +37102,11 @@
</description>
</method>
<method name="pin_joint_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.PinJointParam">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -33449,6 +37114,8 @@
</description>
</method>
<method name="set_active">
+ <return type="void">
+ </return>
<argument index="0" name="active" type="bool">
</argument>
<description>
@@ -33457,19 +37124,21 @@
<method name="shape_create">
<return type="RID">
</return>
- <argument index="0" name="type" type="int">
+ <argument index="0" name="type" type="int" enum="PhysicsServer.ShapeType">
</argument>
<description>
</description>
</method>
<method name="shape_get_data" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="shape" type="RID">
</argument>
<description>
</description>
</method>
<method name="shape_get_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="PhysicsServer.ShapeType">
</return>
<argument index="0" name="shape" type="RID">
</argument>
@@ -33477,6 +37146,8 @@
</description>
</method>
<method name="shape_set_data">
+ <return type="void">
+ </return>
<argument index="0" name="shape" type="RID">
</argument>
<argument index="1" name="data" type="Variant">
@@ -33489,15 +37160,17 @@
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.SliderJointParam">
</argument>
<description>
</description>
</method>
<method name="slider_joint_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.SliderJointParam">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -33523,7 +37196,7 @@
</return>
<argument index="0" name="space" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.SpaceParameter">
</argument>
<description>
</description>
@@ -33537,6 +37210,8 @@
</description>
</method>
<method name="space_set_active">
+ <return type="void">
+ </return>
<argument index="0" name="space" type="RID">
</argument>
<argument index="1" name="active" type="bool">
@@ -33545,9 +37220,11 @@
</description>
</method>
<method name="space_set_param">
+ <return type="void">
+ </return>
<argument index="0" name="space" type="RID">
</argument>
- <argument index="1" name="param" type="int">
+ <argument index="1" name="param" type="int" enum="PhysicsServer.SpaceParameter">
</argument>
<argument index="2" name="value" type="float">
</argument>
@@ -33828,42 +37505,56 @@
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="collision_layer" type="int">
</argument>
<description>
</description>
</method>
<method name="set_exclude">
+ <return type="void">
+ </return>
<argument index="0" name="exclude" type="Array">
</argument>
<description>
</description>
</method>
<method name="set_margin">
+ <return type="void">
+ </return>
<argument index="0" name="margin" type="float">
</argument>
<description>
</description>
</method>
<method name="set_object_type_mask">
+ <return type="void">
+ </return>
<argument index="0" name="object_type_mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_shape">
- <argument index="0" name="shape" type="Shape">
+ <return type="void">
+ </return>
+ <argument index="0" name="shape" type="Resource">
</argument>
<description>
</description>
</method>
<method name="set_shape_rid">
+ <return type="void">
+ </return>
<argument index="0" name="shape" type="RID">
</argument>
<description>
</description>
</method>
<method name="set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="transform" type="Transform">
</argument>
<description>
@@ -33931,13 +37622,15 @@
<method name="get_param" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="PinJoint.Param">
</argument>
<description>
</description>
</method>
<method name="set_param">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="PinJoint.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -33977,6 +37670,8 @@
</description>
</method>
<method name="set_softness">
+ <return type="void">
+ </return>
<argument index="0" name="softness" type="float">
</argument>
<description>
@@ -34170,18 +37865,24 @@
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_depth">
+ <return type="void">
+ </return>
<argument index="0" name="subdivide" type="int">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_width">
+ <return type="void">
+ </return>
<argument index="0" name="subdivide" type="int">
</argument>
<description>
@@ -34212,6 +37913,8 @@
</description>
</method>
<method name="set_plane">
+ <return type="void">
+ </return>
<argument index="0" name="plane" type="Plane">
</argument>
<description>
@@ -34233,6 +37936,12 @@
A Polygon2D is defined by a set of n vertices connected together by line segments, meaning that the vertex 1 will be connected with vertex 2, vertex 2 with vertex 3 ..., vertex n-1 with vertex n and vertex n with vertex 1 in order to close the loop and define a polygon.
</description>
<methods>
+ <method name="get_antialiased" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_color" qualifiers="const">
<return type="Color">
</return>
@@ -34269,7 +37978,7 @@
</description>
</method>
<method name="get_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
Return the polygon texture
@@ -34310,7 +38019,17 @@
Return the list of vertex colors.
</description>
</method>
+ <method name="set_antialiased">
+ <return type="void">
+ </return>
+ <argument index="0" name="antialiased" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -34318,6 +38037,8 @@
</description>
</method>
<method name="set_invert">
+ <return type="void">
+ </return>
<argument index="0" name="invert" type="bool">
</argument>
<description>
@@ -34325,6 +38046,8 @@
</description>
</method>
<method name="set_invert_border">
+ <return type="void">
+ </return>
<argument index="0" name="invert_border" type="float">
</argument>
<description>
@@ -34332,6 +38055,8 @@
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -34339,6 +38064,8 @@
</description>
</method>
<method name="set_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="polygon" type="PoolVector2Array">
</argument>
<description>
@@ -34346,13 +38073,16 @@
</description>
</method>
<method name="set_texture">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
- Set the polygon texture.
</description>
</method>
<method name="set_texture_offset">
+ <return type="void">
+ </return>
<argument index="0" name="texture_offset" type="Vector2">
</argument>
<description>
@@ -34360,6 +38090,8 @@
</description>
</method>
<method name="set_texture_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="texture_rotation" type="float">
</argument>
<description>
@@ -34367,6 +38099,8 @@
</description>
</method>
<method name="set_texture_scale">
+ <return type="void">
+ </return>
<argument index="0" name="texture_scale" type="Vector2">
</argument>
<description>
@@ -34374,6 +38108,8 @@
</description>
</method>
<method name="set_uv">
+ <return type="void">
+ </return>
<argument index="0" name="uv" type="PoolVector2Array">
</argument>
<description>
@@ -34381,6 +38117,8 @@
</description>
</method>
<method name="set_vertex_colors">
+ <return type="void">
+ </return>
<argument index="0" name="vertex_colors" type="PoolColorArray">
</argument>
<description>
@@ -34390,6 +38128,8 @@
</method>
</methods>
<members>
+ <member name="antialiased" type="bool" setter="set_antialiased" getter="get_antialiased" brief="">
+ </member>
<member name="color" type="Color" setter="set_color" getter="get_color" brief="">
</member>
<member name="invert_border" type="float" setter="set_invert_border" getter="get_invert_border" brief="">
@@ -34473,6 +38213,8 @@
</description>
</method>
<method name="set_point_penalty">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="penalty" type="float">
@@ -34481,6 +38223,8 @@
</description>
</method>
<method name="setup">
+ <return type="void">
+ </return>
<argument index="0" name="points" type="PoolVector2Array">
</argument>
<argument index="1" name="connections" type="PoolIntArray">
@@ -35180,27 +38924,35 @@
</description>
</method>
<method name="popup">
- <argument index="0" name="bounds" type="Rect2" default="Rect2(0, 0, 0, 0)">
+ <return type="void">
+ </return>
+ <argument index="0" name="bounds" type="Rect2" default="Rect2( 0, 0, 0, 0 )">
</argument>
<description>
Popup (show the control in modal form).
</description>
</method>
<method name="popup_centered">
- <argument index="0" name="size" type="Vector2" default="Vector2(0, 0)">
+ <return type="void">
+ </return>
+ <argument index="0" name="size" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
Popup (show the control in modal form) in the center of the screen, at the current size, or at a size determined by "size".
</description>
</method>
<method name="popup_centered_minsize">
- <argument index="0" name="minsize" type="Vector2" default="Vector2(0, 0)">
+ <return type="void">
+ </return>
+ <argument index="0" name="minsize" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
Popup (show the control in modal form) in the center of the screen, ensuring the size is never smaller than [code]minsize[/code].
</description>
</method>
<method name="popup_centered_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="ratio" type="float" default="0.75">
</argument>
<description>
@@ -35208,6 +38960,8 @@
</description>
</method>
<method name="set_exclusive">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -35232,10 +38986,10 @@
</signal>
</signals>
<constants>
- <constant name="NOTIFICATION_POST_POPUP" value="80">
+ <constant name="NOTIFICATION_POST_POPUP" value="80" enum="">
Notification sent right after the popup is shown.
</constant>
- <constant name="NOTIFICATION_POPUP_HIDE" value="81">
+ <constant name="NOTIFICATION_POPUP_HIDE" value="81" enum="">
Notification sent right after the popup is hidden.
</constant>
</constants>
@@ -35261,6 +39015,8 @@
</description>
<methods>
<method name="add_check_item">
+ <return type="void">
+ </return>
<argument index="0" name="label" type="String">
</argument>
<argument index="1" name="id" type="int" default="-1">
@@ -35272,6 +39028,8 @@
</description>
</method>
<method name="add_check_shortcut">
+ <return type="void">
+ </return>
<argument index="0" name="shortcut" type="ShortCut">
</argument>
<argument index="1" name="id" type="int" default="-1">
@@ -35282,7 +39040,9 @@
</description>
</method>
<method name="add_icon_check_item">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="label" type="String">
</argument>
@@ -35291,11 +39051,14 @@
<argument index="3" name="accel" type="int" default="0">
</argument>
<description>
- Add a new checkable item with text "label" and icon "texture". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually.
+ Add a new checkable item with text "label" and icon "texture". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be
+ created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually.
</description>
</method>
<method name="add_icon_check_shortcut">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="shortcut" type="ShortCut">
</argument>
@@ -35307,7 +39070,9 @@
</description>
</method>
<method name="add_icon_item">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="label" type="String">
</argument>
@@ -35320,7 +39085,9 @@
</description>
</method>
<method name="add_icon_shortcut">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<argument index="1" name="shortcut" type="ShortCut">
</argument>
@@ -35332,6 +39099,8 @@
</description>
</method>
<method name="add_item">
+ <return type="void">
+ </return>
<argument index="0" name="label" type="String">
</argument>
<argument index="1" name="id" type="int" default="-1">
@@ -35343,11 +39112,15 @@
</description>
</method>
<method name="add_separator">
+ <return type="void">
+ </return>
<description>
Add a separator between items. Separators also occupy an index.
</description>
</method>
<method name="add_shortcut">
+ <return type="void">
+ </return>
<argument index="0" name="shortcut" type="ShortCut">
</argument>
<argument index="1" name="id" type="int" default="-1">
@@ -35358,6 +39131,8 @@
</description>
</method>
<method name="add_submenu_item">
+ <return type="void">
+ </return>
<argument index="0" name="label" type="String">
</argument>
<argument index="1" name="submenu" type="String">
@@ -35369,17 +39144,10 @@
</description>
</method>
<method name="clear">
- <description>
- Clear the popup menu, in effect removing all items.
- </description>
- </method>
- <method name="get_item_id" qualifiers="const">
- <return type="int">
+ <return type="void">
</return>
- <argument index="0" name="idx" type="int">
- </argument>
<description>
- Return the id of the item at index "idx".
+ Clear the popup menu, in effect removing all items.
</description>
</method>
<method name="get_item_accelerator" qualifiers="const">
@@ -35399,7 +39167,7 @@
</description>
</method>
<method name="get_item_icon" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<argument index="0" name="idx" type="int">
</argument>
@@ -35407,6 +39175,15 @@
Return the icon of the item at index "idx".
</description>
</method>
+ <method name="get_item_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ Return the id of the item at index "idx".
+ </description>
+ </method>
<method name="get_item_index" qualifiers="const">
<return type="int">
</return>
@@ -35510,6 +39287,8 @@
</description>
</method>
<method name="remove_item">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -35517,6 +39296,8 @@
</description>
</method>
<method name="set_hide_on_checkable_item_selection">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -35524,22 +39305,17 @@
</description>
</method>
<method name="set_hide_on_item_selection">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
Sets whether or not the PopupMenu will hide on item selection.
</description>
</method>
- <method name="set_item_id">
- <argument index="0" name="idx" type="int">
- </argument>
- <argument index="1" name="id" type="int">
- </argument>
- <description>
- Set the id of the item at index "idx".
- </description>
- </method>
<method name="set_item_accelerator">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="accel" type="int">
@@ -35549,6 +39325,8 @@
</description>
</method>
<method name="set_item_as_checkable">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -35558,6 +39336,8 @@
</description>
</method>
<method name="set_item_as_separator">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -35567,6 +39347,8 @@
</description>
</method>
<method name="set_item_checked">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="checked" type="bool">
@@ -35576,6 +39358,8 @@
</description>
</method>
<method name="set_item_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="disabled" type="bool">
@@ -35585,15 +39369,29 @@
</description>
</method>
<method name="set_item_icon">
+ <return type="void">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <argument index="1" name="icon" type="Texture">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_item_id">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="icon" type="Object">
+ <argument index="1" name="id" type="int">
</argument>
<description>
- Set the icon of the item at index "idx".
+ Set the id of the item at index "idx".
</description>
</method>
<method name="set_item_metadata">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="metadata" type="Variant">
@@ -35603,6 +39401,8 @@
</description>
</method>
<method name="set_item_shortcut">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="shortcut" type="ShortCut">
@@ -35613,6 +39413,8 @@
</description>
</method>
<method name="set_item_submenu">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="submenu" type="String">
@@ -35622,6 +39424,8 @@
</description>
</method>
<method name="set_item_text">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="text" type="String">
@@ -35631,6 +39435,8 @@
</description>
</method>
<method name="set_item_tooltip">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="tooltip" type="String">
@@ -35639,6 +39445,8 @@
</description>
</method>
<method name="toggle_item_checked">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -35718,88 +39526,6 @@
</theme_item>
</theme_items>
</class>
-<class name="Portal" inherits="VisualInstance" category="Core">
- <brief_description>
- Portals provide virtual openings to rooms.
- </brief_description>
- <description>
- Portals provide virtual openings to [VisualInstance] nodes, so cameras can look at them from the outside. Note that portals are a visibility optimization technique, and are in no way related to the game of the same name (as in, they are not used for teleportation). For more information on how rooms and portals work, see [VisualInstance]. Portals are represented as 2D convex polygon shapes (in the X,Y local plane), and are placed on the surface of the areas occupied by a [VisualInstance], to indicate that the room can be accessed or looked-at through them. If two rooms are next to each other, and two similar portals in each of them share the same world position (and are parallel and opposed to each other), they will automatically "connect" and form "doors" (for example, the portals that connect a kitchen to a living room are placed in the door they share). Portals must always have a [VisualInstance] node as a parent, grandparent or far parent, or else they will not be active.
- </description>
- <methods>
- <method name="get_connect_range" qualifiers="const">
- <return type="float">
- </return>
- <description>
- Return the range for auto-connecting two portals from different rooms sharing the same space.
- </description>
- </method>
- <method name="get_disable_distance" qualifiers="const">
- <return type="float">
- </return>
- <description>
- Return the distance threshold for disabling the portal. Every time that the portal goes beyond "distance", it disables itself, becoming the opaque color (see [method set_disabled_color]).
- </description>
- </method>
- <method name="get_disabled_color" qualifiers="const">
- <return type="Color">
- </return>
- <description>
- Return the color for when the portal goes beyond the disable distance (see [method set_disable_distance]) and becomes disabled.
- </description>
- </method>
- <method name="get_shape" qualifiers="const">
- <return type="PoolVector2Array">
- </return>
- <description>
- Return the portal shape. The shape is an array of [Vector2] points, representing a convex polygon in the X,Y plane.
- </description>
- </method>
- <method name="is_enabled" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- Return whether the portal is active. When disabled it causes the parent [VisualInstance] to not be visible any longer when looking through the portal.
- </description>
- </method>
- <method name="set_connect_range">
- <argument index="0" name="range" type="float">
- </argument>
- <description>
- Set the range for auto-connecting two portals from different rooms sharing the same space.
- </description>
- </method>
- <method name="set_disable_distance">
- <argument index="0" name="distance" type="float">
- </argument>
- <description>
- Set the distance threshold for disabling the portal. Every time that the portal goes beyond "distance", it disables itself, becoming the opaque color (see [method set_disabled_color]).
- </description>
- </method>
- <method name="set_disabled_color">
- <argument index="0" name="color" type="Color">
- </argument>
- <description>
- When the portal goes beyond the disable distance (see [method set_disable_distance]), it becomes opaque and displayed with color "color".
- </description>
- </method>
- <method name="set_enabled">
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- Enable the portal (it is enabled by default though), disabling it will cause the parent [VisualInstance] to not be visible any longer when looking through the portal.
- </description>
- </method>
- <method name="set_shape">
- <argument index="0" name="points" type="PoolVector2Array">
- </argument>
- <description>
- Set the portal shape. The shape is an array of [Vector2] points, representing a convex polygon in the X,Y plane.
- </description>
- </method>
- </methods>
- <constants>
- </constants>
-</class>
<class name="Position2D" inherits="Node2D" category="Core">
<brief_description>
Generic 2D Position hint for editing.
@@ -35837,6 +39563,8 @@
</description>
</method>
<method name="set_material">
+ <return type="void">
+ </return>
<argument index="0" name="material" type="Material">
</argument>
<description>
@@ -35887,30 +39615,40 @@
</description>
</method>
<method name="set_left_to_right">
+ <return type="void">
+ </return>
<argument index="0" name="left_to_right" type="float">
</argument>
<description>
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_depth">
+ <return type="void">
+ </return>
<argument index="0" name="segments" type="int">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_height">
+ <return type="void">
+ </return>
<argument index="0" name="segments" type="int">
</argument>
<description>
</description>
</method>
<method name="set_subdivide_width">
+ <return type="void">
+ </return>
<argument index="0" name="segments" type="int">
</argument>
<description>
@@ -35920,7 +39658,7 @@
<members>
<member name="left_to_right" type="float" setter="set_left_to_right" getter="get_left_to_right" brief="">
</member>
- <member name="size" type="Vector2" setter="set_size" getter="get_size" brief="">
+ <member name="size" type="Vector3" setter="set_size" getter="get_size" brief="">
</member>
<member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief="">
</member>
@@ -36029,103 +39767,135 @@
</description>
</method>
<method name="get_texture_size" qualifiers="const">
- <return type="int">
+ <return type="int" enum="ProceduralSky.TextureSize">
</return>
<description>
</description>
</method>
<method name="set_ground_bottom_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_ground_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ground_energy">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_ground_horizon_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_sky_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sky_energy">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sky_horizon_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_sky_top_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_sun_angle_max">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sun_angle_min">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sun_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_sun_curve">
+ <return type="void">
+ </return>
<argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sun_energy">
+ <return type="void">
+ </return>
<argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sun_latitude">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
</description>
</method>
<method name="set_sun_longitude">
+ <return type="void">
+ </return>
<argument index="0" name="degrees" type="float">
</argument>
<description>
</description>
</method>
<method name="set_texture_size">
- <argument index="0" name="size" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="size" type="int" enum="ProceduralSky.TextureSize">
</argument>
<description>
</description>
@@ -36162,10 +39932,22 @@
</member>
<member name="sun_longitude" type="float" setter="set_sun_longitude" getter="get_sun_longitude" brief="">
</member>
- <member name="texture_size" type="int" setter="set_texture_size" getter="get_texture_size" brief="">
+ <member name="texture_size" type="int" setter="set_texture_size" getter="get_texture_size" brief="" enum="ProceduralSky.TextureSize">
</member>
</members>
<constants>
+ <constant name="TEXTURE_SIZE_256" value="0">
+ </constant>
+ <constant name="TEXTURE_SIZE_512" value="1">
+ </constant>
+ <constant name="TEXTURE_SIZE_1024" value="2">
+ </constant>
+ <constant name="TEXTURE_SIZE_2048" value="3">
+ </constant>
+ <constant name="TEXTURE_SIZE_4096" value="4">
+ </constant>
+ <constant name="TEXTURE_SIZE_MAX" value="5">
+ </constant>
</constants>
</class>
<class name="ProgressBar" inherits="Range" category="Core">
@@ -36183,6 +39965,8 @@
</description>
</method>
<method name="set_percent_visible">
+ <return type="void">
+ </return>
<argument index="0" name="visible" type="bool">
</argument>
<description>
@@ -36208,6 +39992,160 @@
</theme_item>
</theme_items>
</class>
+<class name="ProjectSettings" inherits="Object" category="Core">
+ <brief_description>
+ Contains global variables accessible from everywhere.
+ </brief_description>
+ <description>
+ Contains global variables accessible from everywhere. Use the normal [Object] API, such as "ProjectSettings.get(variable)", "ProjectSettings.set(variable,value)" or "ProjectSettings.has(variable)" to access them. Variables stored in project.godot are also loaded into ProjectSettings, making this object very useful for reading custom game configuration options.
+ </description>
+ <methods>
+ <method name="add_property_info">
+ <return type="void">
+ </return>
+ <argument index="0" name="hint" type="Dictionary">
+ </argument>
+ <description>
+ Add a custom property info to a property. The dictionary must contain: name:[String](the name of the property) and type:[int](see TYPE_* in [@Global Scope]), and optionally hint:[int](see PROPERTY_HINT_* in [@Global Scope]), hint_string:[String].
+ Example:
+ [codeblock]
+ ProjectSettings.set("category/property_name", 0)
+
+ var property_info = {
+ "name": "category/property_name",
+ "type": TYPE_INT,
+ "hint": PROPERTY_HINT_ENUM,
+ "hint_string": "one,two,three"
+ }
+
+ ProjectSettings.add_property_info(property_info)
+ [/codeblock]
+ </description>
+ </method>
+ <method name="clear">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ Clear the whole configuration (not recommended, may break things).
+ </description>
+ </method>
+ <method name="get_order" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ Return the order of a configuration value (influences when saved to the config file).
+ </description>
+ </method>
+ <method name="get_singleton" qualifiers="const">
+ <return type="Object">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="globalize_path" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ Convert a localized path (res://) to a full native OS path.
+ </description>
+ </method>
+ <method name="has" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ Return true if a configuration value is present.
+ </description>
+ </method>
+ <method name="has_singleton" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="load_resource_pack">
+ <return type="bool">
+ </return>
+ <argument index="0" name="pack" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="localize_path" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ Convert a path to a localized path (res:// path).
+ </description>
+ </method>
+ <method name="property_can_revert">
+ <return type="bool">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="property_get_revert">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="save">
+ <return type="int" enum="Error">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="save_custom">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="file" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_initial_value">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_order">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="pos" type="int">
+ </argument>
+ <description>
+ Set the order of a configuration value (influences when saved to the config file).
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="ProximityGroup" inherits="Spatial" category="Core">
<brief_description>
General purpose proximity-detection node.
@@ -36217,6 +40155,8 @@
</description>
<methods>
<method name="broadcast">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="parameters" type="Variant">
@@ -36231,18 +40171,24 @@
</description>
</method>
<method name="set_dispatch_mode">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="int">
</argument>
<description>
</description>
</method>
<method name="set_grid_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_group_name">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -36509,6 +40455,8 @@
</description>
</method>
<method name="set_as_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="float">
</argument>
<description>
@@ -36516,18 +40464,24 @@
</description>
</method>
<method name="set_exp_ratio">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_max">
+ <return type="void">
+ </return>
<argument index="0" name="maximum" type="float">
</argument>
<description>
</description>
</method>
<method name="set_min">
+ <return type="void">
+ </return>
<argument index="0" name="minimum" type="float">
</argument>
<description>
@@ -36535,6 +40489,8 @@
</description>
</method>
<method name="set_page">
+ <return type="void">
+ </return>
<argument index="0" name="pagesize" type="float">
</argument>
<description>
@@ -36542,6 +40498,8 @@
</description>
</method>
<method name="set_step">
+ <return type="void">
+ </return>
<argument index="0" name="step" type="float">
</argument>
<description>
@@ -36549,24 +40507,32 @@
</description>
</method>
<method name="set_use_rounded_values">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_value">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="float">
</argument>
<description>
</description>
</method>
<method name="share">
- <argument index="0" name="with" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="with" type="Node">
</argument>
<description>
</description>
</method>
<method name="unshare">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -36619,6 +40585,8 @@
</description>
<methods>
<method name="add_exception">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Object">
</argument>
<description>
@@ -36626,17 +40594,23 @@
</description>
</method>
<method name="add_exception_rid">
+ <return type="void">
+ </return>
<argument index="0" name="rid" type="RID">
</argument>
<description>
</description>
</method>
<method name="clear_exceptions">
+ <return type="void">
+ </return>
<description>
Removes all collision exception for this ray.
</description>
</method>
<method name="force_raycast_update">
+ <return type="void">
+ </return>
<description>
Updates the collision information in case if this object's properties changed during the current frame (for example position, rotation or the cast_point). Note, [code]set_enabled[/code] is not required for this to work.
</description>
@@ -36705,6 +40679,8 @@
</description>
</method>
<method name="remove_exception">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Object">
</argument>
<description>
@@ -36712,12 +40688,16 @@
</description>
</method>
<method name="remove_exception_rid">
+ <return type="void">
+ </return>
<argument index="0" name="rid" type="RID">
</argument>
<description>
</description>
</method>
<method name="set_cast_to">
+ <return type="void">
+ </return>
<argument index="0" name="local_point" type="Vector3">
</argument>
<description>
@@ -36725,6 +40705,8 @@
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
@@ -36732,6 +40714,8 @@
</description>
</method>
<method name="set_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -36739,6 +40723,8 @@
</description>
</method>
<method name="set_type_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
@@ -36774,6 +40760,8 @@
</description>
<methods>
<method name="add_exception">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Object">
</argument>
<description>
@@ -36781,17 +40769,23 @@
</description>
</method>
<method name="add_exception_rid">
+ <return type="void">
+ </return>
<argument index="0" name="rid" type="RID">
</argument>
<description>
</description>
</method>
<method name="clear_exceptions">
+ <return type="void">
+ </return>
<description>
Removes all collision exception for this ray.
</description>
</method>
<method name="force_raycast_update">
+ <return type="void">
+ </return>
<description>
Updates the collision information in case if this object's properties changed during the current frame (for example position, rotation or the cast_point). Note, [code]set_enabled[/code] is not required for this to work.
</description>
@@ -36867,6 +40861,8 @@
</description>
</method>
<method name="remove_exception">
+ <return type="void">
+ </return>
<argument index="0" name="node" type="Object">
</argument>
<description>
@@ -36874,12 +40870,16 @@
</description>
</method>
<method name="remove_exception_rid">
+ <return type="void">
+ </return>
<argument index="0" name="rid" type="RID">
</argument>
<description>
</description>
</method>
<method name="set_cast_to">
+ <return type="void">
+ </return>
<argument index="0" name="local_point" type="Vector2">
</argument>
<description>
@@ -36887,6 +40887,8 @@
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
@@ -36894,6 +40896,8 @@
</description>
</method>
<method name="set_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -36901,6 +40905,8 @@
</description>
</method>
<method name="set_exclude_parent_body">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="bool">
</argument>
<description>
@@ -36908,6 +40914,8 @@
</description>
</method>
<method name="set_type_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
@@ -36943,6 +40951,8 @@
</description>
</method>
<method name="set_length">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
@@ -36972,6 +40982,8 @@
</description>
</method>
<method name="set_length">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
@@ -37349,6 +41361,8 @@
</description>
</method>
<method name="set_extents">
+ <return type="void">
+ </return>
<argument index="0" name="extents" type="Vector2">
</argument>
<description>
@@ -37378,6 +41392,8 @@
</description>
</method>
<method name="reference">
+ <return type="void">
+ </return>
<description>
Increase the internal reference counter. Use this only if you really know what you are doing.
</description>
@@ -37470,7 +41486,7 @@
</description>
</method>
<method name="get_update_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="ReflectionProbe.UpdateMode">
</return>
<description>
</description>
@@ -37488,73 +41504,97 @@
</description>
</method>
<method name="set_as_interior">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_cull_mask">
+ <return type="void">
+ </return>
<argument index="0" name="layers" type="int">
</argument>
<description>
</description>
</method>
<method name="set_enable_box_projection">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_enable_shadows">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_extents">
+ <return type="void">
+ </return>
<argument index="0" name="extents" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_intensity">
+ <return type="void">
+ </return>
<argument index="0" name="intensity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_interior_ambient">
+ <return type="void">
+ </return>
<argument index="0" name="ambient" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_interior_ambient_energy">
+ <return type="void">
+ </return>
<argument index="0" name="ambient_energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_interior_ambient_probe_contribution">
+ <return type="void">
+ </return>
<argument index="0" name="ambient_probe_contribution" type="float">
</argument>
<description>
</description>
</method>
<method name="set_max_distance">
+ <return type="void">
+ </return>
<argument index="0" name="max_distance" type="float">
</argument>
<description>
</description>
</method>
<method name="set_origin_offset">
+ <return type="void">
+ </return>
<argument index="0" name="origin_offset" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_update_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="ReflectionProbe.UpdateMode">
</argument>
<description>
</description>
@@ -37567,7 +41607,7 @@
</member>
<member name="enable_shadows" type="bool" setter="set_enable_shadows" getter="are_shadows_enabled" brief="">
</member>
- <member name="extents" type="Vector2" setter="set_extents" getter="get_extents" brief="">
+ <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" brief="">
</member>
<member name="intensity" type="float" setter="set_intensity" getter="get_intensity" brief="">
</member>
@@ -37581,9 +41621,9 @@
</member>
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" brief="">
</member>
- <member name="origin_offset" type="Vector2" setter="set_origin_offset" getter="get_origin_offset" brief="">
+ <member name="origin_offset" type="Vector3" setter="set_origin_offset" getter="get_origin_offset" brief="">
</member>
- <member name="update_mode" type="int" setter="set_update_mode" getter="get_update_mode" brief="">
+ <member name="update_mode" type="int" setter="set_update_mode" getter="get_update_mode" brief="" enum="ReflectionProbe.UpdateMode">
</member>
</members>
<constants>
@@ -37593,7 +41633,7 @@
</constant>
</constants>
</class>
-<class name="RegEx" inherits="Resource" category="Core">
+<class name="RegEx" inherits="Reference" category="Core">
<brief_description>
Simple regular expression matcher.
</brief_description>
@@ -37625,12 +41665,14 @@
</description>
<methods>
<method name="clear">
+ <return type="void">
+ </return>
<description>
This method resets the state of the object, as it was freshly created. Namely, it unassigns the regular expression of this object.
</description>
</method>
<method name="compile">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="pattern" type="String">
</argument>
@@ -37669,9 +41711,9 @@
<method name="search" qualifiers="const">
<return type="RegExMatch">
</return>
- <argument index="0" name="text" type="String">
+ <argument index="0" name="subject" type="String">
</argument>
- <argument index="1" name="start" type="int" default="0">
+ <argument index="1" name="offset" type="int" default="0">
</argument>
<argument index="2" name="end" type="int" default="-1">
</argument>
@@ -37682,13 +41724,13 @@
<method name="sub" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="text" type="String">
+ <argument index="0" name="subject" type="String">
</argument>
<argument index="1" name="replacement" type="String">
</argument>
<argument index="2" name="all" type="bool" default="false">
</argument>
- <argument index="3" name="start" type="int" default="0">
+ <argument index="3" name="offset" type="int" default="0">
</argument>
<argument index="4" name="end" type="int" default="-1">
</argument>
@@ -37697,10 +41739,6 @@
</description>
</method>
</methods>
- <members>
- <member name="pattern" type="String" setter="compile" getter="get_pattern" brief="">
- </member>
- </members>
<constants>
</constants>
</class>
@@ -37710,15 +41748,6 @@
<description>
</description>
<methods>
- <method name="expand" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="template" type="String">
- </argument>
- <description>
- Using results from the search, returns the specified string with escapes and backreferences such as [code]\1[/code] and [code]\g&lt;name&gt;[/code] expanded and resolved.
- </description>
- </method>
<method name="get_end" qualifiers="const">
<return type="int">
</return>
@@ -37728,13 +41757,6 @@
Returns the end position of the match in the string. An integer can be specified for numeric groups or a string for named groups. Returns -1 if that group wasn't found or doesn't exist. Defaults to 0 (whole pattern).
</description>
</method>
- <method name="get_group_array" qualifiers="const">
- <return type="Array">
- </return>
- <description>
- Returns an array of the results of the numeric groups.
- </description>
- </method>
<method name="get_group_count" qualifiers="const">
<return type="int">
</return>
@@ -37742,15 +41764,8 @@
Returns the number of numeric capturing groups.
</description>
</method>
- <method name="get_name_dict" qualifiers="const">
- <return type="Dictionary">
- </return>
- <description>
- Returns a dictionary containing the named capturing groups and their results.
- </description>
- </method>
<method name="get_names" qualifiers="const">
- <return type="Array">
+ <return type="Dictionary">
</return>
<description>
Returns an array of names of named capturing groups.
@@ -37774,6 +41789,18 @@
Returns the result of the match in the string. An integer can be specified for numeric groups or a string for named groups. Returns -1 if that group wasn't found or doesn't exist. Defaults to 0 (whole pattern).
</description>
</method>
+ <method name="get_strings" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subject" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
</constants>
@@ -37815,30 +41842,40 @@
</description>
</method>
<method name="set_remote_node">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_update_position">
+ <return type="void">
+ </return>
<argument index="0" name="update_remote_position" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_update_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="update_remote_rotation" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_update_scale">
+ <return type="void">
+ </return>
<argument index="0" name="update_remote_scale" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_use_global_coordinates">
+ <return type="void">
+ </return>
<argument index="0" name="use_global_coordinates" type="bool">
</argument>
<description>
@@ -37897,30 +41934,40 @@
</description>
</method>
<method name="set_remote_node">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_update_position">
+ <return type="void">
+ </return>
<argument index="0" name="update_remote_position" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_update_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="update_remote_rotation" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_update_scale">
+ <return type="void">
+ </return>
<argument index="0" name="update_remote_scale" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_use_global_coordinates">
+ <return type="void">
+ </return>
<argument index="0" name="use_global_coordinates" type="bool">
</argument>
<description>
@@ -37951,11 +41998,13 @@
</description>
<methods>
<method name="_setup_local_to_scene" qualifiers="virtual">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="duplicate" qualifiers="const">
- <return type="Object">
+ <return type="Resource">
</return>
<argument index="0" name="subresources" type="bool" default="false">
</argument>
@@ -37996,12 +42045,16 @@
</description>
</method>
<method name="set_local_to_scene">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_name">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -38009,6 +42062,8 @@
</description>
</method>
<method name="set_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -38016,10 +42071,14 @@
</description>
</method>
<method name="setup_local_to_scene">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="take_over_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -38073,7 +42132,7 @@
</description>
<methods>
<method name="get_resource">
- <return type="Object">
+ <return type="Resource">
</return>
<description>
Return the loaded resource (only if loaded). Otherwise, returns null.
@@ -38094,14 +42153,14 @@
</description>
</method>
<method name="poll">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<description>
Poll the load. If OK is returned, this means poll will have to be called again. If ERR_FILE_EOF is returned, them the load has finished and the resource can be obtained by calling [method get_resource].
</description>
</method>
<method name="wait">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<description>
</description>
@@ -38167,6 +42226,8 @@
</description>
</method>
<method name="set_abort_on_missing_resources">
+ <return type="void">
+ </return>
<argument index="0" name="abort" type="bool">
</argument>
<description>
@@ -38186,16 +42247,17 @@
</description>
<methods>
<method name="add_resource">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="resource" type="Object">
+ <argument index="1" name="resource" type="Resource">
</argument>
<description>
- Add a resource to the preloader. Set the text-id that will be used to identify it (retrieve it/erase it/etc).
</description>
</method>
<method name="get_resource" qualifiers="const">
- <return type="Object">
+ <return type="Resource">
</return>
<argument index="0" name="name" type="String">
</argument>
@@ -38220,6 +42282,8 @@
</description>
</method>
<method name="remove_resource">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -38227,6 +42291,8 @@
</description>
</method>
<method name="rename_resource">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="newname" type="String">
@@ -38254,14 +42320,14 @@
<method name="get_recognized_extensions">
<return type="PoolStringArray">
</return>
- <argument index="0" name="type" type="Object">
+ <argument index="0" name="type" type="Resource">
</argument>
<description>
Return the list of extensions available for saving a resource of a given type.
</description>
</method>
<method name="save">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -38298,19 +42364,23 @@
</description>
<methods>
<method name="add_image">
+ <return type="void">
+ </return>
<argument index="0" name="image" type="Texture">
</argument>
<description>
</description>
</method>
<method name="add_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
</description>
</method>
<method name="append_bbcode">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="bbcode" type="String">
</argument>
@@ -38318,6 +42388,8 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -38396,11 +42468,13 @@
</description>
</method>
<method name="newline">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="parse_bbcode">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="bbcode" type="String">
</argument>
@@ -38408,104 +42482,138 @@
</description>
</method>
<method name="pop">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="push_align">
- <argument index="0" name="align" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="align" type="int" enum="RichTextLabel.Align">
</argument>
<description>
</description>
</method>
<method name="push_cell">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="push_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="push_font">
+ <return type="void">
+ </return>
<argument index="0" name="font" type="Font">
</argument>
<description>
</description>
</method>
<method name="push_indent">
+ <return type="void">
+ </return>
<argument index="0" name="level" type="int">
</argument>
<description>
</description>
</method>
<method name="push_list">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="RichTextLabel.ListType">
</argument>
<description>
</description>
</method>
<method name="push_meta">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="Variant">
</argument>
<description>
</description>
</method>
<method name="push_table">
+ <return type="void">
+ </return>
<argument index="0" name="columns" type="int">
</argument>
<description>
</description>
</method>
<method name="push_underline">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="remove_line">
<return type="bool">
</return>
- <argument index="0" name="arg0" type="int">
+ <argument index="0" name="line" type="int">
</argument>
<description>
</description>
</method>
<method name="scroll_to_line">
+ <return type="void">
+ </return>
<argument index="0" name="line" type="int">
</argument>
<description>
</description>
</method>
<method name="set_bbcode">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
</description>
</method>
<method name="set_meta_underline">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_percent_visible">
+ <return type="void">
+ </return>
<argument index="0" name="percent_visible" type="float">
</argument>
<description>
</description>
</method>
<method name="set_scroll_active">
+ <return type="void">
+ </return>
<argument index="0" name="active" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_scroll_follow">
+ <return type="void">
+ </return>
<argument index="0" name="follow" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_selection_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -38513,12 +42621,16 @@
</description>
</method>
<method name="set_tab_size">
+ <return type="void">
+ </return>
<argument index="0" name="spaces" type="int">
</argument>
<description>
</description>
</method>
<method name="set_table_column_expand">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="expand" type="bool">
@@ -38529,18 +42641,24 @@
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
</description>
</method>
<method name="set_use_bbcode">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_visible_characters">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -38639,6 +42757,8 @@
</description>
<methods>
<method name="_integrate_forces" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="state" type="PhysicsDirectBodyState">
</argument>
<description>
@@ -38646,6 +42766,8 @@
</description>
</method>
<method name="apply_impulse">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector3">
</argument>
<argument index="1" name="impulse" type="Vector3">
@@ -38669,7 +42791,7 @@
</description>
</method>
<method name="get_axis_lock" qualifiers="const">
- <return type="int">
+ <return type="int" enum="RigidBody.AxisLock">
</return>
<description>
Return the current axis lock of the body. One of AXIS_LOCK_* enum.
@@ -38732,7 +42854,7 @@
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="RigidBody.Mode">
</return>
<description>
Return the current body mode, see [method set_mode].
@@ -38781,6 +42903,8 @@
</description>
</method>
<method name="set_angular_damp">
+ <return type="void">
+ </return>
<argument index="0" name="angular_damp" type="float">
</argument>
<description>
@@ -38788,6 +42912,8 @@
</description>
</method>
<method name="set_angular_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="angular_velocity" type="Vector3">
</argument>
<description>
@@ -38795,13 +42921,17 @@
</description>
</method>
<method name="set_axis_lock">
- <argument index="0" name="axis_lock" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="axis_lock" type="int" enum="RigidBody.AxisLock">
</argument>
<description>
Set the axis lock of the body, from the AXIS_LOCK_* enum. Axis lock stops the body from moving along the specified axis(X/Y/Z) and rotating along the other two axes.
</description>
</method>
<method name="set_axis_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="axis_velocity" type="Vector3">
</argument>
<description>
@@ -38809,6 +42939,8 @@
</description>
</method>
<method name="set_bounce">
+ <return type="void">
+ </return>
<argument index="0" name="bounce" type="float">
</argument>
<description>
@@ -38816,6 +42948,8 @@
</description>
</method>
<method name="set_can_sleep">
+ <return type="void">
+ </return>
<argument index="0" name="able_to_sleep" type="bool">
</argument>
<description>
@@ -38824,6 +42958,8 @@
</description>
</method>
<method name="set_contact_monitor">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -38831,6 +42967,8 @@
</description>
</method>
<method name="set_friction">
+ <return type="void">
+ </return>
<argument index="0" name="friction" type="float">
</argument>
<description>
@@ -38838,6 +42976,8 @@
</description>
</method>
<method name="set_gravity_scale">
+ <return type="void">
+ </return>
<argument index="0" name="gravity_scale" type="float">
</argument>
<description>
@@ -38845,6 +42985,8 @@
</description>
</method>
<method name="set_linear_damp">
+ <return type="void">
+ </return>
<argument index="0" name="linear_damp" type="float">
</argument>
<description>
@@ -38852,6 +42994,8 @@
</description>
</method>
<method name="set_linear_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="linear_velocity" type="Vector3">
</argument>
<description>
@@ -38859,6 +43003,8 @@
</description>
</method>
<method name="set_mass">
+ <return type="void">
+ </return>
<argument index="0" name="mass" type="float">
</argument>
<description>
@@ -38866,6 +43012,8 @@
</description>
</method>
<method name="set_max_contacts_reported">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -38873,13 +43021,17 @@
</description>
</method>
<method name="set_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="RigidBody.Mode">
</argument>
<description>
Set the body mode, from the MODE_* enum. This allows to change to a static body or a character body.
</description>
</method>
<method name="set_sleeping">
+ <return type="void">
+ </return>
<argument index="0" name="sleeping" type="bool">
</argument>
<description>
@@ -38887,6 +43039,8 @@
</description>
</method>
<method name="set_use_continuous_collision_detection">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -38895,6 +43049,8 @@
</description>
</method>
<method name="set_use_custom_integrator">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -38902,6 +43058,8 @@
</description>
</method>
<method name="set_weight">
+ <return type="void">
+ </return>
<argument index="0" name="weight" type="float">
</argument>
<description>
@@ -38914,7 +43072,7 @@
</member>
<member name="angular_velocity" type="Vector3" setter="set_angular_velocity" getter="get_angular_velocity" brief="">
</member>
- <member name="axis_lock" type="int" setter="set_axis_lock" getter="get_axis_lock" brief="">
+ <member name="axis_lock" type="int" setter="set_axis_lock" getter="get_axis_lock" brief="" enum="RigidBody.AxisLock">
</member>
<member name="bounce" type="float" setter="set_bounce" getter="get_bounce" brief="">
</member>
@@ -38938,7 +43096,7 @@
</member>
<member name="mass" type="float" setter="set_mass" getter="get_mass" brief="">
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="RigidBody.Mode">
</member>
<member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping" brief="">
</member>
@@ -39020,6 +43178,8 @@
</description>
<methods>
<method name="_integrate_forces" qualifiers="virtual">
+ <return type="void">
+ </return>
<argument index="0" name="state" type="Physics2DDirectBodyState">
</argument>
<description>
@@ -39027,6 +43187,8 @@
</description>
</method>
<method name="add_force">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<argument index="1" name="force" type="Vector2">
@@ -39036,6 +43198,8 @@
</description>
</method>
<method name="apply_impulse">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<argument index="1" name="impulse" type="Vector2">
@@ -39087,7 +43251,7 @@
</description>
</method>
<method name="get_continuous_collision_detection_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="RigidBody2D.CCDMode">
</return>
<description>
Return whether this body is using continuous collision detection.
@@ -39143,7 +43307,7 @@
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="RigidBody2D.Mode">
</return>
<description>
Return the current body mode, see [method set_mode].
@@ -39185,6 +43349,8 @@
</description>
</method>
<method name="set_angular_damp">
+ <return type="void">
+ </return>
<argument index="0" name="angular_damp" type="float">
</argument>
<description>
@@ -39192,6 +43358,8 @@
</description>
</method>
<method name="set_angular_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="angular_velocity" type="float">
</argument>
<description>
@@ -39199,6 +43367,8 @@
</description>
</method>
<method name="set_applied_force">
+ <return type="void">
+ </return>
<argument index="0" name="force" type="Vector2">
</argument>
<description>
@@ -39206,6 +43376,8 @@
</description>
</method>
<method name="set_applied_torque">
+ <return type="void">
+ </return>
<argument index="0" name="torque" type="float">
</argument>
<description>
@@ -39213,6 +43385,8 @@
</description>
</method>
<method name="set_axis_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="axis_velocity" type="Vector2">
</argument>
<description>
@@ -39220,6 +43394,8 @@
</description>
</method>
<method name="set_bounce">
+ <return type="void">
+ </return>
<argument index="0" name="bounce" type="float">
</argument>
<description>
@@ -39227,6 +43403,8 @@
</description>
</method>
<method name="set_can_sleep">
+ <return type="void">
+ </return>
<argument index="0" name="able_to_sleep" type="bool">
</argument>
<description>
@@ -39235,6 +43413,8 @@
</description>
</method>
<method name="set_contact_monitor">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -39242,7 +43422,9 @@
</description>
</method>
<method name="set_continuous_collision_detection_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="RigidBody2D.CCDMode">
</argument>
<description>
Set the continuous collision detection mode from the enum CCD_MODE_*.
@@ -39250,6 +43432,8 @@
</description>
</method>
<method name="set_friction">
+ <return type="void">
+ </return>
<argument index="0" name="friction" type="float">
</argument>
<description>
@@ -39257,6 +43441,8 @@
</description>
</method>
<method name="set_gravity_scale">
+ <return type="void">
+ </return>
<argument index="0" name="gravity_scale" type="float">
</argument>
<description>
@@ -39264,6 +43450,8 @@
</description>
</method>
<method name="set_inertia">
+ <return type="void">
+ </return>
<argument index="0" name="inertia" type="float">
</argument>
<description>
@@ -39271,6 +43459,8 @@
</description>
</method>
<method name="set_linear_damp">
+ <return type="void">
+ </return>
<argument index="0" name="linear_damp" type="float">
</argument>
<description>
@@ -39278,6 +43468,8 @@
</description>
</method>
<method name="set_linear_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="linear_velocity" type="Vector2">
</argument>
<description>
@@ -39285,6 +43477,8 @@
</description>
</method>
<method name="set_mass">
+ <return type="void">
+ </return>
<argument index="0" name="mass" type="float">
</argument>
<description>
@@ -39292,6 +43486,8 @@
</description>
</method>
<method name="set_max_contacts_reported">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -39299,13 +43495,17 @@
</description>
</method>
<method name="set_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="RigidBody2D.Mode">
</argument>
<description>
Set the body mode, from the MODE_* enum. This allows to change to a static body or a character body.
</description>
</method>
<method name="set_sleeping">
+ <return type="void">
+ </return>
<argument index="0" name="sleeping" type="bool">
</argument>
<description>
@@ -39313,6 +43513,8 @@
</description>
</method>
<method name="set_use_custom_integrator">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -39320,6 +43522,8 @@
</description>
</method>
<method name="set_weight">
+ <return type="void">
+ </return>
<argument index="0" name="weight" type="float">
</argument>
<description>
@@ -39333,7 +43537,7 @@
</argument>
<argument index="1" name="margin" type="float" default="0.08">
</argument>
- <argument index="2" name="result" type="Physics2DTestMotionResult" default="NULL">
+ <argument index="2" name="result" type="Physics2DTestMotionResult" default="null">
</argument>
<description>
Return whether the body would collide, if it tried to move in the given vector. This method allows two extra parameters: A margin, which increases slightly the size of the shapes involved in the collision detection, and an object of type [Physics2DTestMotionResult], which will store additional information about the collision (should there be one).
@@ -39353,7 +43557,7 @@
</member>
<member name="contacts_reported" type="int" setter="set_max_contacts_reported" getter="get_max_contacts_reported" brief="">
</member>
- <member name="continuous_cd" type="int" setter="set_continuous_collision_detection_mode" getter="get_continuous_collision_detection_mode" brief="">
+ <member name="continuous_cd" type="int" setter="set_continuous_collision_detection_mode" getter="get_continuous_collision_detection_mode" brief="" enum="RigidBody2D.CCDMode">
</member>
<member name="custom_integrator" type="bool" setter="set_use_custom_integrator" getter="is_using_custom_integrator" brief="">
</member>
@@ -39367,7 +43571,7 @@
</member>
<member name="mass" type="float" setter="set_mass" getter="get_mass" brief="">
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="RigidBody2D.Mode">
</member>
<member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping" brief="">
</member>
@@ -39447,60 +43651,6 @@
</constant>
</constants>
</class>
-<class name="Room" inherits="VisualInstance" category="Core">
- <brief_description>
- Room data resource.
- </brief_description>
- <description>
- Room contains the data to define the bounds of a scene (using a BSP Tree). It is instanced by a [VisualInstance] node to create rooms. See that class documentation for more information about rooms.
- </description>
- <methods>
- <method name="get_room" qualifiers="const">
- <return type="Room">
- </return>
- <description>
- </description>
- </method>
- <method name="set_room">
- <argument index="0" name="room" type="Room">
- </argument>
- <description>
- </description>
- </method>
- </methods>
- <members>
- <member name="room/room" type="Area" setter="set_room" getter="get_room" brief="">
- </member>
- </members>
- <constants>
- </constants>
-</class>
-<class name="RoomBounds" inherits="Resource" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- <method name="get_geometry_hint" qualifiers="const">
- <return type="PoolVector3Array">
- </return>
- <description>
- </description>
- </method>
- <method name="set_geometry_hint">
- <argument index="0" name="triangles" type="PoolVector3Array">
- </argument>
- <description>
- </description>
- </method>
- </methods>
- <members>
- <member name="geometry_hint" type="PoolVector3Array" setter="set_geometry_hint" getter="get_geometry_hint" brief="">
- </member>
- </members>
- <constants>
- </constants>
-</class>
<class name="SceneState" inherits="Reference" category="Core">
<brief_description>
</brief_description>
@@ -39678,6 +43828,8 @@
</description>
<methods>
<method name="call_group" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="group" type="String">
</argument>
<argument index="1" name="method" type="String">
@@ -39686,6 +43838,8 @@
</description>
</method>
<method name="call_group_flags" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="flags" type="int">
</argument>
<argument index="1" name="group" type="String">
@@ -39696,7 +43850,7 @@
</description>
</method>
<method name="change_scene">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -39704,7 +43858,7 @@
</description>
</method>
<method name="change_scene_to">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="packed_scene" type="PackedScene">
</argument>
@@ -39728,7 +43882,7 @@
</description>
</method>
<method name="get_edited_scene_root" qualifiers="const">
- <return type="Object">
+ <return type="Node">
</return>
<description>
</description>
@@ -39771,6 +43925,12 @@
<description>
</description>
</method>
+ <method name="get_rpc_sender_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="has_group" qualifiers="const">
<return type="bool">
</return>
@@ -39798,12 +43958,6 @@
<description>
</description>
</method>
- <method name="is_editor_hint" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
<method name="is_input_handled">
<return type="bool">
</return>
@@ -39830,14 +43984,18 @@
</description>
</method>
<method name="notify_group">
- <argument index="0" name="call_flags" type="String">
+ <return type="void">
+ </return>
+ <argument index="0" name="group" type="String">
</argument>
- <argument index="1" name="group" type="int">
+ <argument index="1" name="notification" type="int">
</argument>
<description>
</description>
</method>
<method name="notify_group_flags">
+ <return type="void">
+ </return>
<argument index="0" name="call_flags" type="int">
</argument>
<argument index="1" name="group" type="String">
@@ -39848,68 +44006,80 @@
</description>
</method>
<method name="queue_delete">
+ <return type="void">
+ </return>
<argument index="0" name="obj" type="Object">
</argument>
<description>
</description>
</method>
<method name="quit">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="reload_current_scene">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<description>
</description>
</method>
<method name="set_auto_accept_quit">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_current_scene">
+ <return type="void">
+ </return>
<argument index="0" name="child_node" type="Node">
</argument>
<description>
</description>
</method>
<method name="set_debug_collisions_hint">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_debug_navigation_hint">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_edited_scene_root">
- <argument index="0" name="scene" type="Object">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_editor_hint">
- <argument index="0" name="enable" type="bool">
+ <return type="void">
+ </return>
+ <argument index="0" name="scene" type="Node">
</argument>
<description>
</description>
</method>
<method name="set_group">
- <argument index="0" name="call_flags" type="String">
+ <return type="void">
+ </return>
+ <argument index="0" name="group" type="String">
</argument>
- <argument index="1" name="group" type="String">
+ <argument index="1" name="property" type="String">
</argument>
- <argument index="2" name="property" type="Variant">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
</method>
<method name="set_group_flags">
+ <return type="void">
+ </return>
<argument index="0" name="call_flags" type="int">
</argument>
<argument index="1" name="group" type="String">
@@ -39922,10 +44092,14 @@
</description>
</method>
<method name="set_input_as_handled">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set_network_peer">
+ <return type="void">
+ </return>
<argument index="0" name="peer" type="NetworkedMultiplayerPeer">
</argument>
<description>
@@ -39933,24 +44107,32 @@
</description>
</method>
<method name="set_pause">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_refuse_new_network_connections">
+ <return type="void">
+ </return>
<argument index="0" name="refuse" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_screen_stretch">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="SceneTree.StretchMode">
</argument>
- <argument index="1" name="aspect" type="int">
+ <argument index="1" name="aspect" type="int" enum="SceneTree.StretchAspect">
</argument>
<argument index="2" name="minsize" type="Vector2">
</argument>
+ <argument index="3" name="shrink" type="int" default="1">
+ </argument>
<description>
</description>
</method>
@@ -40055,6 +44237,8 @@
</description>
</method>
<method name="set_time_left">
+ <return type="void">
+ </return>
<argument index="0" name="time" type="float">
</argument>
<description>
@@ -40085,6 +44269,12 @@
Return true if this script can be instance (ie not a library).
</description>
</method>
+ <method name="get_node_type" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_source_code" qualifiers="const">
<return type="String">
</return>
@@ -40092,6 +44282,14 @@
Return the script source code (if available).
</description>
</method>
+ <method name="has_script_signal" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="signal_name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="has_source_code" qualifiers="const">
<return type="bool">
</return>
@@ -40108,8 +44306,14 @@
Return true if a given object uses an instance of this script.
</description>
</method>
+ <method name="is_tool" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="reload">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="keep_state" type="bool" default="false">
</argument>
@@ -40117,6 +44321,8 @@
</description>
</method>
<method name="set_source_code">
+ <return type="void">
+ </return>
<argument index="0" name="source" type="String">
</argument>
<description>
@@ -40127,6 +44333,46 @@
<constants>
</constants>
</class>
+<class name="ScriptEditor" inherits="PanelContainer" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_current_script">
+ <return type="Script">
+ </return>
+ <description>
+ Returns a [Script] that is currently active in editor.
+ </description>
+ </method>
+ <method name="get_open_scripts" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ Returns an array with all [Script] objects which are currently open in editor.
+ </description>
+ </method>
+ </methods>
+ <signals>
+ <signal name="editor_script_changed">
+ <argument index="0" name="script" type="Object">
+ </argument>
+ <description>
+ Emitted when user changed active script. Argument is a freshly activated [Script].
+ </description>
+ </signal>
+ <signal name="script_close">
+ <argument index="0" name="script" type="Object">
+ </argument>
+ <description>
+ Emitted when editor is about to close the active script. Argument is a [Script] that is going to be closed.
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
<class name="ScrollBar" inherits="Range" category="Core">
<brief_description>
Base class for scroll bars.
@@ -40142,6 +44388,8 @@
</description>
</method>
<method name="set_custom_step">
+ <return type="void">
+ </return>
<argument index="0" name="step" type="float">
</argument>
<description>
@@ -40152,6 +44400,12 @@
<member name="custom_step" type="float" setter="set_custom_step" getter="get_custom_step" brief="">
</member>
</members>
+ <signals>
+ <signal name="scrolling">
+ <description>
+ </description>
+ </signal>
+ </signals>
<constants>
</constants>
</class>
@@ -40192,6 +44446,8 @@
</description>
</method>
<method name="set_enable_h_scroll">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -40199,6 +44455,8 @@
</description>
</method>
<method name="set_enable_v_scroll">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -40206,6 +44464,8 @@
</description>
</method>
<method name="set_h_scroll">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -40213,6 +44473,8 @@
</description>
</method>
<method name="set_v_scroll">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -40229,44 +44491,6 @@
<constants>
</constants>
</class>
-<class name="ScriptEditor" inherits="PanelContainer" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- <method name="get_current_script">
- <return type="Script">
- </return>
- <description>
- Returns a [Script] that is currently active in editor.
- </description>
- </method>
- <method name="get_open_scripts">
- <return type="Array">
- </return>
- <description>
- Returns an array with all [Script] objects which are currently open in editor.
- </description>
- </method>
- </methods>
- <signals>
- <signal name="editor_script_changed">
- <argument index="0" name="script" type="Script">
- </argument>
- <description>
- Emitted when user changed active script. Argument is a freshly activated [Script].
- </description>
- </signal>
- <signal name="script_close">
- <argument index="0" name="script" type="Script">
- </argument>
- <description>
- Emitted when editor is about to close the active script. Argument is a [Script] that is going to be closed.
- </description>
- </signal>
- </signals>
-</class>
<class name="SegmentShape2D" inherits="Shape2D" category="Core">
<brief_description>
Segment Shape for 2D Collision Detection.
@@ -40290,6 +44514,8 @@
</description>
</method>
<method name="set_a">
+ <return type="void">
+ </return>
<argument index="0" name="a" type="Vector2">
</argument>
<description>
@@ -40297,6 +44523,8 @@
</description>
</method>
<method name="set_b">
+ <return type="void">
+ </return>
<argument index="0" name="b" type="Vector2">
</argument>
<description>
@@ -40322,14 +44550,14 @@
</description>
<methods>
<method name="post">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<description>
Lowers the [Semaphore], allowing one more thread in.
</description>
</method>
<method name="wait">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<description>
Tries to wait for the [Semaphore], if its value is zero, blocks until non-zero.
@@ -40374,7 +44602,7 @@
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Shader.Mode">
</return>
<description>
</description>
@@ -40388,12 +44616,16 @@
</description>
</method>
<method name="set_code">
+ <return type="void">
+ </return>
<argument index="0" name="code" type="String">
</argument>
<description>
</description>
</method>
<method name="set_default_texture_param">
+ <return type="void">
+ </return>
<argument index="0" name="param" type="String">
</argument>
<argument index="1" name="texture" type="Texture">
@@ -40436,12 +44668,16 @@
</description>
</method>
<method name="set_shader">
+ <return type="void">
+ </return>
<argument index="0" name="shader" type="Shader">
</argument>
<description>
</description>
</method>
<method name="set_shader_param">
+ <return type="void">
+ </return>
<argument index="0" name="param" type="String">
</argument>
<argument index="1" name="value" type="Variant">
@@ -40543,6 +44779,8 @@
</description>
</method>
<method name="set_custom_solver_bias">
+ <return type="void">
+ </return>
<argument index="0" name="bias" type="float">
</argument>
<description>
@@ -40591,6 +44829,8 @@
</description>
</method>
<method name="set_shortcut">
+ <return type="void">
+ </return>
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
@@ -40613,6 +44853,8 @@
</description>
<methods>
<method name="add_bone">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -40620,6 +44862,8 @@
</description>
</method>
<method name="bind_child_node_to_bone">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="node" type="Node">
@@ -40629,6 +44873,8 @@
</description>
</method>
<method name="clear_bones">
+ <return type="void">
+ </return>
<description>
Clear all the bones in this skeleton.
</description>
@@ -40727,6 +44973,8 @@
</description>
</method>
<method name="set_bone_custom_pose">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="custom_pose" type="Transform">
@@ -40735,6 +44983,8 @@
</description>
</method>
<method name="set_bone_disable_rest">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="disable" type="bool">
@@ -40743,6 +44993,8 @@
</description>
</method>
<method name="set_bone_global_pose">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="pose" type="Transform">
@@ -40751,6 +45003,8 @@
</description>
</method>
<method name="set_bone_parent">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="parent_idx" type="int">
@@ -40760,6 +45014,8 @@
</description>
</method>
<method name="set_bone_pose">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="pose" type="Transform">
@@ -40769,6 +45025,8 @@
</description>
</method>
<method name="set_bone_rest">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="rest" type="Transform">
@@ -40778,6 +45036,8 @@
</description>
</method>
<method name="unbind_child_node_from_bone">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<argument index="1" name="node" type="Node">
@@ -40787,6 +45047,8 @@
</description>
</method>
<method name="unparent_bone_and_rest">
+ <return type="void">
+ </return>
<argument index="0" name="bone_idx" type="int">
</argument>
<description>
@@ -40794,7 +45056,7 @@
</method>
</methods>
<constants>
- <constant name="NOTIFICATION_UPDATE_SKELETON" value="50">
+ <constant name="NOTIFICATION_UPDATE_SKELETON" value="50" enum="">
</constant>
</constants>
</class>
@@ -40805,32 +45067,40 @@
</description>
<methods>
<method name="get_radiance_size" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Sky.RadianceSize">
</return>
<description>
</description>
</method>
<method name="set_radiance_size">
- <argument index="0" name="size" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="size" type="int" enum="Sky.RadianceSize">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="radiance_size" type="int" setter="set_radiance_size" getter="get_radiance_size" brief="">
+ <member name="radiance_size" type="int" setter="set_radiance_size" getter="get_radiance_size" brief="" enum="Sky.RadianceSize">
</member>
</members>
<constants>
- <constant name="RADIANCE_SIZE_256" value="0">
+ <constant name="RADIANCE_SIZE_32" value="0">
+ </constant>
+ <constant name="RADIANCE_SIZE_64" value="1">
</constant>
- <constant name="RADIANCE_SIZE_512" value="1">
+ <constant name="RADIANCE_SIZE_128" value="2">
</constant>
- <constant name="RADIANCE_SIZE_1024" value="2">
+ <constant name="RADIANCE_SIZE_256" value="3">
</constant>
- <constant name="RADIANCE_SIZE_2048" value="3">
+ <constant name="RADIANCE_SIZE_512" value="4">
</constant>
- <constant name="RADIANCE_SIZE_MAX" value="4">
+ <constant name="RADIANCE_SIZE_1024" value="5">
+ </constant>
+ <constant name="RADIANCE_SIZE_2048" value="6">
+ </constant>
+ <constant name="RADIANCE_SIZE_MAX" value="7">
</constant>
</constants>
</class>
@@ -40863,12 +45133,16 @@
</description>
</method>
<method name="set_editable">
+ <return type="void">
+ </return>
<argument index="0" name="editable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_ticks">
+ <return type="void">
+ </return>
<argument index="0" name="count" type="int">
</argument>
<description>
@@ -40876,6 +45150,8 @@
</description>
</method>
<method name="set_ticks_on_borders">
+ <return type="void">
+ </return>
<argument index="0" name="ticks_on_border" type="bool">
</argument>
<description>
@@ -40886,7 +45162,7 @@
<members>
<member name="editable" type="bool" setter="set_editable" getter="is_editable" brief="">
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" brief="">
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" brief="" enum="Control.FocusMode">
</member>
<member name="tick_count" type="int" setter="set_ticks" getter="get_ticks" brief="">
</member>
@@ -40905,13 +45181,15 @@
<method name="get_param" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
+ <argument index="0" name="param" type="int" enum="SliderJoint.Param">
</argument>
<description>
</description>
</method>
<method name="set_param">
- <argument index="0" name="param" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="SliderJoint.Param">
</argument>
<argument index="1" name="value" type="float">
</argument>
@@ -41036,7 +45314,7 @@
</description>
</method>
<method name="get_parent_spatial" qualifiers="const">
- <return type="Object">
+ <return type="Spatial">
</return>
<description>
Return the parent [Spatial], or an empty [Object] if no parent exists or parent is not of type [Spatial].
@@ -41082,6 +45360,8 @@
</description>
</method>
<method name="global_rotate">
+ <return type="void">
+ </return>
<argument index="0" name="normal" type="Vector3">
</argument>
<argument index="1" name="radians" type="float">
@@ -41090,12 +45370,16 @@
</description>
</method>
<method name="global_translate">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="hide">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -41130,6 +45414,8 @@
</description>
</method>
<method name="look_at">
+ <return type="void">
+ </return>
<argument index="0" name="target" type="Vector3">
</argument>
<argument index="1" name="up" type="Vector3">
@@ -41138,6 +45424,8 @@
</description>
</method>
<method name="look_at_from_pos">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector3">
</argument>
<argument index="1" name="target" type="Vector3">
@@ -41148,10 +45436,14 @@
</description>
</method>
<method name="orthonormalize">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="rotate">
+ <return type="void">
+ </return>
<argument index="0" name="normal" type="Vector3">
</argument>
<argument index="1" name="radians" type="float">
@@ -41160,36 +45452,48 @@
</description>
</method>
<method name="rotate_x">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
</description>
</method>
<method name="rotate_y">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
</description>
</method>
<method name="rotate_z">
+ <return type="void">
+ </return>
<argument index="0" name="radians" type="float">
</argument>
<description>
</description>
</method>
<method name="set_as_toplevel">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_gizmo">
+ <return type="void">
+ </return>
<argument index="0" name="gizmo" type="SpatialGizmo">
</argument>
<description>
</description>
</method>
<method name="set_global_transform">
+ <return type="void">
+ </return>
<argument index="0" name="global" type="Transform">
</argument>
<description>
@@ -41197,28 +45501,38 @@
</description>
</method>
<method name="set_identity">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="set_ignore_transform_notification">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_notify_local_transform">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_notify_transform">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_rotation">
+ <return type="void">
+ </return>
<argument index="0" name="rotation_rad" type="Vector3">
</argument>
<description>
@@ -41226,6 +45540,8 @@
</description>
</method>
<method name="set_rotation_deg">
+ <return type="void">
+ </return>
<argument index="0" name="rotation_deg" type="Vector3">
</argument>
<description>
@@ -41233,12 +45549,16 @@
</description>
</method>
<method name="set_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_transform">
+ <return type="void">
+ </return>
<argument index="0" name="local" type="Transform">
</argument>
<description>
@@ -41246,28 +45566,54 @@
</description>
</method>
<method name="set_translation">
+ <return type="void">
+ </return>
<argument index="0" name="translation" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_visible">
- <argument index="0" name="arg0" type="bool">
+ <return type="void">
+ </return>
+ <argument index="0" name="visible" type="bool">
</argument>
<description>
</description>
</method>
<method name="show">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="to_global" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="local_point" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="to_local" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="global_point" type="Vector3">
+ </argument>
<description>
</description>
</method>
<method name="translate">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="update_gizmo">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -41295,14 +45641,14 @@
</signal>
</signals>
<constants>
- <constant name="NOTIFICATION_TRANSFORM_CHANGED" value="29">
+ <constant name="NOTIFICATION_TRANSFORM_CHANGED" value="29" enum="">
Spatial nodes receive this notification with their global transform changes. This means that either the current or a parent node changed its transform.
</constant>
- <constant name="NOTIFICATION_ENTER_WORLD" value="41">
+ <constant name="NOTIFICATION_ENTER_WORLD" value="41" enum="">
</constant>
- <constant name="NOTIFICATION_EXIT_WORLD" value="42">
+ <constant name="NOTIFICATION_EXIT_WORLD" value="42" enum="">
</constant>
- <constant name="NOTIFICATION_VISIBILITY_CHANGED" value="43">
+ <constant name="NOTIFICATION_VISIBILITY_CHANGED" value="43" enum="">
</constant>
</constants>
</class>
@@ -41328,20 +45674,32 @@
<description>
</description>
</method>
+ <method name="get_alpha_scissor_threshold" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_anisotropy" qualifiers="const">
<return type="float">
</return>
<description>
</description>
</method>
+ <method name="get_ao_texture_channel" qualifiers="const">
+ <return type="int" enum="SpatialMaterial.TextureChannel">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_billboard_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.BillboardMode">
</return>
<description>
</description>
</method>
<method name="get_blend_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.BlendMode">
</return>
<description>
</description>
@@ -41359,7 +45717,7 @@
</description>
</method>
<method name="get_cull_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.CullMode">
</return>
<description>
</description>
@@ -41377,7 +45735,7 @@
</description>
</method>
<method name="get_depth_draw_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.DepthDrawMode">
</return>
<description>
</description>
@@ -41389,19 +45747,19 @@
</description>
</method>
<method name="get_detail_blend_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.BlendMode">
</return>
<description>
</description>
</method>
<method name="get_detail_uv" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.DetailUV">
</return>
<description>
</description>
</method>
<method name="get_diffuse_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.DiffuseMode">
</return>
<description>
</description>
@@ -41421,7 +45779,7 @@
<method name="get_feature" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="feature" type="int">
+ <argument index="0" name="feature" type="int" enum="SpatialMaterial.Feature">
</argument>
<description>
</description>
@@ -41429,7 +45787,7 @@
<method name="get_flag" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="arg0" type="int">
+ <argument index="0" name="flag" type="int" enum="SpatialMaterial.Flags">
</argument>
<description>
</description>
@@ -41452,6 +45810,12 @@
<description>
</description>
</method>
+ <method name="get_metallic_texture_channel" qualifiers="const">
+ <return type="int" enum="SpatialMaterial.TextureChannel">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_normal_scale" qualifiers="const">
<return type="float">
</return>
@@ -41488,6 +45852,12 @@
<description>
</description>
</method>
+ <method name="get_refraction_texture_channel" qualifiers="const">
+ <return type="int" enum="SpatialMaterial.TextureChannel">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_rim" qualifiers="const">
<return type="float">
</return>
@@ -41506,6 +45876,12 @@
<description>
</description>
</method>
+ <method name="get_roughness_texture_channel" qualifiers="const">
+ <return type="int" enum="SpatialMaterial.TextureChannel">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_specular" qualifiers="const">
<return type="float">
</return>
@@ -41513,7 +45889,7 @@
</description>
</method>
<method name="get_specular_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpatialMaterial.SpecularMode">
</return>
<description>
</description>
@@ -41527,7 +45903,7 @@
<method name="get_texture" qualifiers="const">
<return type="Texture">
</return>
- <argument index="0" name="param" type="Texture">
+ <argument index="0" name="param" type="int" enum="SpatialMaterial.TextureParam">
</argument>
<description>
</description>
@@ -41581,109 +45957,161 @@
</description>
</method>
<method name="set_albedo">
+ <return type="void">
+ </return>
<argument index="0" name="albedo" type="Color">
</argument>
<description>
</description>
</method>
+ <method name="set_alpha_scissor_threshold">
+ <return type="void">
+ </return>
+ <argument index="0" name="threshold" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_anisotropy">
+ <return type="void">
+ </return>
<argument index="0" name="anisotropy" type="float">
</argument>
<description>
</description>
</method>
+ <method name="set_ao_texture_channel">
+ <return type="void">
+ </return>
+ <argument index="0" name="channel" type="int" enum="SpatialMaterial.TextureChannel">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_billboard_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="SpatialMaterial.BillboardMode">
</argument>
<description>
</description>
</method>
<method name="set_blend_mode">
- <argument index="0" name="blend_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="blend_mode" type="int" enum="SpatialMaterial.BlendMode">
</argument>
<description>
</description>
</method>
<method name="set_clearcoat">
+ <return type="void">
+ </return>
<argument index="0" name="clearcoat" type="float">
</argument>
<description>
</description>
</method>
<method name="set_clearcoat_gloss">
+ <return type="void">
+ </return>
<argument index="0" name="clearcoat_gloss" type="float">
</argument>
<description>
</description>
</method>
<method name="set_cull_mode">
- <argument index="0" name="cull_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="cull_mode" type="int" enum="SpatialMaterial.CullMode">
</argument>
<description>
</description>
</method>
<method name="set_depth_deep_parallax">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_depth_deep_parallax_max_layers">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
</description>
</method>
<method name="set_depth_deep_parallax_min_layers">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
</description>
</method>
<method name="set_depth_draw_mode">
- <argument index="0" name="depth_draw_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="depth_draw_mode" type="int" enum="SpatialMaterial.DepthDrawMode">
</argument>
<description>
</description>
</method>
<method name="set_depth_scale">
+ <return type="void">
+ </return>
<argument index="0" name="depth_scale" type="float">
</argument>
<description>
</description>
</method>
<method name="set_detail_blend_mode">
- <argument index="0" name="detail_blend_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="detail_blend_mode" type="int" enum="SpatialMaterial.BlendMode">
</argument>
<description>
</description>
</method>
<method name="set_detail_uv">
- <argument index="0" name="detail_uv" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="detail_uv" type="int" enum="SpatialMaterial.DetailUV">
</argument>
<description>
</description>
</method>
<method name="set_diffuse_mode">
- <argument index="0" name="diffuse_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="diffuse_mode" type="int" enum="SpatialMaterial.DiffuseMode">
</argument>
<description>
</description>
</method>
<method name="set_emission">
+ <return type="void">
+ </return>
<argument index="0" name="emission" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_emission_energy">
+ <return type="void">
+ </return>
<argument index="0" name="emission_energy" type="float">
</argument>
<description>
</description>
</method>
<method name="set_feature">
- <argument index="0" name="feature" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="feature" type="int" enum="SpatialMaterial.Feature">
</argument>
<argument index="1" name="enable" type="bool">
</argument>
@@ -41691,7 +46119,9 @@
</description>
</method>
<method name="set_flag">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="SpatialMaterial.Flags">
</argument>
<argument index="1" name="enable" type="bool">
</argument>
@@ -41699,140 +46129,210 @@
</description>
</method>
<method name="set_grow">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="float">
</argument>
<description>
</description>
</method>
<method name="set_grow_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_line_width">
+ <return type="void">
+ </return>
<argument index="0" name="line_width" type="float">
</argument>
<description>
</description>
</method>
<method name="set_metallic">
+ <return type="void">
+ </return>
<argument index="0" name="metallic" type="float">
</argument>
<description>
</description>
</method>
+ <method name="set_metallic_texture_channel">
+ <return type="void">
+ </return>
+ <argument index="0" name="channel" type="int" enum="SpatialMaterial.TextureChannel">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_normal_scale">
+ <return type="void">
+ </return>
<argument index="0" name="normal_scale" type="float">
</argument>
<description>
</description>
</method>
<method name="set_particles_anim_h_frames">
+ <return type="void">
+ </return>
<argument index="0" name="frames" type="int">
</argument>
<description>
</description>
</method>
<method name="set_particles_anim_loop">
+ <return type="void">
+ </return>
<argument index="0" name="frames" type="int">
</argument>
<description>
</description>
</method>
<method name="set_particles_anim_v_frames">
+ <return type="void">
+ </return>
<argument index="0" name="frames" type="int">
</argument>
<description>
</description>
</method>
<method name="set_point_size">
+ <return type="void">
+ </return>
<argument index="0" name="point_size" type="float">
</argument>
<description>
</description>
</method>
<method name="set_refraction">
+ <return type="void">
+ </return>
<argument index="0" name="refraction" type="float">
</argument>
<description>
</description>
</method>
+ <method name="set_refraction_texture_channel">
+ <return type="void">
+ </return>
+ <argument index="0" name="channel" type="int" enum="SpatialMaterial.TextureChannel">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_rim">
+ <return type="void">
+ </return>
<argument index="0" name="rim" type="float">
</argument>
<description>
</description>
</method>
<method name="set_rim_tint">
+ <return type="void">
+ </return>
<argument index="0" name="rim_tint" type="float">
</argument>
<description>
</description>
</method>
<method name="set_roughness">
+ <return type="void">
+ </return>
<argument index="0" name="roughness" type="float">
</argument>
<description>
</description>
</method>
+ <method name="set_roughness_texture_channel">
+ <return type="void">
+ </return>
+ <argument index="0" name="channel" type="int" enum="SpatialMaterial.TextureChannel">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_specular">
+ <return type="void">
+ </return>
<argument index="0" name="specular" type="float">
</argument>
<description>
</description>
</method>
<method name="set_specular_mode">
- <argument index="0" name="specular_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="specular_mode" type="int" enum="SpatialMaterial.SpecularMode">
</argument>
<description>
</description>
</method>
<method name="set_subsurface_scattering_strength">
+ <return type="void">
+ </return>
<argument index="0" name="strength" type="float">
</argument>
<description>
</description>
</method>
<method name="set_texture">
- <argument index="0" name="param" type="Texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="param" type="int" enum="SpatialMaterial.TextureParam">
</argument>
- <argument index="1" name="texture" type="Object">
+ <argument index="1" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_uv1_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_uv1_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_uv1_triplanar_blend_sharpness">
+ <return type="void">
+ </return>
<argument index="0" name="sharpness" type="float">
</argument>
<description>
</description>
</method>
<method name="set_uv2_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_uv2_scale">
+ <return type="void">
+ </return>
<argument index="0" name="scale" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_uv2_triplanar_blend_sharpness">
+ <return type="void">
+ </return>
<argument index="0" name="sharpness" type="float">
</argument>
<description>
@@ -41856,6 +46356,8 @@
</member>
<member name="ao_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
+ <member name="ao_texture_channel" type="int" setter="set_ao_texture_channel" getter="get_ao_texture_channel" brief="" enum="SpatialMaterial.TextureChannel">
+ </member>
<member name="clearcoat" type="float" setter="set_clearcoat" getter="get_clearcoat" brief="">
</member>
<member name="clearcoat_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
@@ -41878,7 +46380,7 @@
</member>
<member name="detail_albedo" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="detail_blend_mode" type="int" setter="set_detail_blend_mode" getter="get_detail_blend_mode" brief="">
+ <member name="detail_blend_mode" type="int" setter="set_detail_blend_mode" getter="get_detail_blend_mode" brief="" enum="SpatialMaterial.BlendMode">
</member>
<member name="detail_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -41886,7 +46388,7 @@
</member>
<member name="detail_normal" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="detail_uv_layer" type="int" setter="set_detail_uv" getter="get_detail_uv" brief="">
+ <member name="detail_uv_layer" type="int" setter="set_detail_uv" getter="get_detail_uv" brief="" enum="SpatialMaterial.DetailUV">
</member>
<member name="emission" type="Color" setter="set_emission" getter="get_emission" brief="">
</member>
@@ -41898,7 +46400,7 @@
</member>
<member name="flags_fixed_size" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
- <member name="flags_on_top" type="bool" setter="set_flag" getter="get_flag" brief="">
+ <member name="flags_no_depth_test" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
<member name="flags_transparent" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -41906,27 +46408,35 @@
</member>
<member name="flags_use_point_size" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
+ <member name="flags_vertex_lighting" type="bool" setter="set_flag" getter="get_flag" brief="">
+ </member>
+ <member name="flags_world_triplanar" type="bool" setter="set_flag" getter="get_flag" brief="">
+ </member>
<member name="metallic" type="float" setter="set_metallic" getter="get_metallic" brief="">
</member>
<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" brief="">
</member>
<member name="metallic_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
+ <member name="metallic_texture_channel" type="int" setter="set_metallic_texture_channel" getter="get_metallic_texture_channel" brief="" enum="SpatialMaterial.TextureChannel">
+ </member>
<member name="normal_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
<member name="normal_scale" type="float" setter="set_normal_scale" getter="get_normal_scale" brief="">
</member>
<member name="normal_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="params_billboard_mode" type="int" setter="set_billboard_mode" getter="get_billboard_mode" brief="">
+ <member name="params_alpha_scissor_threshold" type="float" setter="set_alpha_scissor_threshold" getter="get_alpha_scissor_threshold" brief="">
</member>
- <member name="params_blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" brief="">
+ <member name="params_billboard_mode" type="int" setter="set_billboard_mode" getter="get_billboard_mode" brief="" enum="SpatialMaterial.BillboardMode">
</member>
- <member name="params_cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" brief="">
+ <member name="params_blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" brief="" enum="SpatialMaterial.BlendMode">
</member>
- <member name="params_depth_draw_mode" type="int" setter="set_depth_draw_mode" getter="get_depth_draw_mode" brief="">
+ <member name="params_cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" brief="" enum="SpatialMaterial.CullMode">
</member>
- <member name="params_diffuse_mode" type="int" setter="set_diffuse_mode" getter="get_diffuse_mode" brief="">
+ <member name="params_depth_draw_mode" type="int" setter="set_depth_draw_mode" getter="get_depth_draw_mode" brief="" enum="SpatialMaterial.DepthDrawMode">
+ </member>
+ <member name="params_diffuse_mode" type="int" setter="set_diffuse_mode" getter="get_diffuse_mode" brief="" enum="SpatialMaterial.DiffuseMode">
</member>
<member name="params_grow" type="bool" setter="set_grow_enabled" getter="is_grow_enabled" brief="">
</member>
@@ -41936,11 +46446,13 @@
</member>
<member name="params_point_size" type="float" setter="set_point_size" getter="get_point_size" brief="">
</member>
- <member name="params_specular_mode" type="int" setter="set_specular_mode" getter="get_specular_mode" brief="">
+ <member name="params_specular_mode" type="int" setter="set_specular_mode" getter="get_specular_mode" brief="" enum="SpatialMaterial.SpecularMode">
+ </member>
+ <member name="params_use_alpha_scissor" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
<member name="particles_anim_h_frames" type="int" setter="set_particles_anim_h_frames" getter="get_particles_anim_h_frames" brief="">
</member>
- <member name="particles_anim_loop" type="bool" setter="set_particles_anim_loop" getter="get_particles_anim_loop" brief="">
+ <member name="particles_anim_loop" type="int" setter="set_particles_anim_loop" getter="get_particles_anim_loop" brief="">
</member>
<member name="particles_anim_v_frames" type="int" setter="set_particles_anim_v_frames" getter="get_particles_anim_v_frames" brief="">
</member>
@@ -41950,6 +46462,8 @@
</member>
<member name="refraction_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
+ <member name="refraction_texture_channel" type="int" setter="set_refraction_texture_channel" getter="get_refraction_texture_channel" brief="" enum="SpatialMaterial.TextureChannel">
+ </member>
<member name="rim" type="float" setter="set_rim" getter="get_rim" brief="">
</member>
<member name="rim_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
@@ -41962,6 +46476,8 @@
</member>
<member name="roughness_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
+ <member name="roughness_texture_channel" type="int" setter="set_roughness_texture_channel" getter="get_roughness_texture_channel" brief="" enum="SpatialMaterial.TextureChannel">
+ </member>
<member name="subsurf_scatter_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
<member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength" brief="">
@@ -42074,17 +46590,29 @@
</constant>
<constant name="FLAG_UNSHADED" value="0">
</constant>
- <constant name="FLAG_ONTOP" value="1">
+ <constant name="FLAG_USE_VERTEX_LIGHTING" value="1">
+ </constant>
+ <constant name="FLAG_DISABLE_DEPTH_TEST" value="2">
+ </constant>
+ <constant name="FLAG_ALBEDO_FROM_VERTEX_COLOR" value="3">
+ </constant>
+ <constant name="FLAG_SRGB_VERTEX_COLOR" value="4">
+ </constant>
+ <constant name="FLAG_USE_POINT_SIZE" value="5">
+ </constant>
+ <constant name="FLAG_FIXED_SIZE" value="6">
+ </constant>
+ <constant name="FLAG_UV1_USE_TRIPLANAR" value="7">
</constant>
- <constant name="FLAG_ALBEDO_FROM_VERTEX_COLOR" value="2">
+ <constant name="FLAG_UV2_USE_TRIPLANAR" value="8">
</constant>
- <constant name="FLAG_SRGB_VERTEX_COLOR" value="3">
+ <constant name="FLAG_AO_ON_UV2" value="10">
</constant>
- <constant name="FLAG_USE_POINT_SIZE" value="4">
+ <constant name="FLAG_USE_ALPHA_SCISSOR" value="11">
</constant>
- <constant name="FLAG_FIXED_SIZE" value="5">
+ <constant name="FLAG_TRIPLANAR_USE_WORLD" value="9">
</constant>
- <constant name="FLAG_MAX" value="9">
+ <constant name="FLAG_MAX" value="12">
</constant>
<constant name="DIFFUSE_LAMBERT" value="0">
</constant>
@@ -42114,6 +46642,16 @@
</constant>
<constant name="BILLBOARD_PARTICLES" value="3">
</constant>
+ <constant name="TEXTURE_CHANNEL_RED" value="0">
+ </constant>
+ <constant name="TEXTURE_CHANNEL_GREEN" value="1">
+ </constant>
+ <constant name="TEXTURE_CHANNEL_BLUE" value="2">
+ </constant>
+ <constant name="TEXTURE_CHANNEL_ALPHA" value="3">
+ </constant>
+ <constant name="TEXTURE_CHANNEL_GRAYSCALE" value="4">
+ </constant>
</constants>
</class>
<class name="SpatialVelocityTracker" inherits="Reference" category="Core">
@@ -42135,18 +46673,24 @@
</description>
</method>
<method name="reset">
+ <return type="void">
+ </return>
<argument index="0" name="position" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_track_fixed_step">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="update_position">
+ <return type="void">
+ </return>
<argument index="0" name="position" type="Vector3">
</argument>
<description>
@@ -42193,30 +46737,40 @@
</description>
</method>
<method name="set_height">
+ <return type="void">
+ </return>
<argument index="0" name="height" type="float">
</argument>
<description>
</description>
</method>
<method name="set_is_hemisphere">
+ <return type="void">
+ </return>
<argument index="0" name="is_hemisphere" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_radial_segments">
+ <return type="void">
+ </return>
<argument index="0" name="radial_segments" type="int">
</argument>
<description>
</description>
</method>
<method name="set_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
<method name="set_rings">
+ <return type="void">
+ </return>
<argument index="0" name="rings" type="int">
</argument>
<description>
@@ -42251,6 +46805,8 @@
</description>
</method>
<method name="set_radius">
+ <return type="void">
+ </return>
<argument index="0" name="radius" type="float">
</argument>
<description>
@@ -42273,7 +46829,7 @@
</description>
<methods>
<method name="get_line_edit">
- <return type="Object">
+ <return type="LineEdit">
</return>
<description>
</description>
@@ -42299,6 +46855,8 @@
</description>
</method>
<method name="set_editable">
+ <return type="void">
+ </return>
<argument index="0" name="editable" type="bool">
</argument>
<description>
@@ -42306,6 +46864,8 @@
</description>
</method>
<method name="set_prefix">
+ <return type="void">
+ </return>
<argument index="0" name="prefix" type="String">
</argument>
<description>
@@ -42313,6 +46873,8 @@
</description>
</method>
<method name="set_suffix">
+ <return type="void">
+ </return>
<argument index="0" name="suffix" type="String">
</argument>
<description>
@@ -42344,7 +46906,7 @@
</description>
<methods>
<method name="get_dragger_visibility" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SplitContainer.DraggerVisibility">
</return>
<description>
Return visibility of the split dragger (one of [DRAGGER_VISIBLE], [DRAGGER_HIDDEN] or [DRAGGER_HIDDEN_COLLAPSED]).
@@ -42365,6 +46927,8 @@
</description>
</method>
<method name="set_collapsed">
+ <return type="void">
+ </return>
<argument index="0" name="collapsed" type="bool">
</argument>
<description>
@@ -42372,13 +46936,17 @@
</description>
</method>
<method name="set_dragger_visibility">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="SplitContainer.DraggerVisibility">
</argument>
<description>
Set visibility of the split dragger ([i]mode[/i] must be one of [DRAGGER_VISIBLE], [DRAGGER_HIDDEN] or [DRAGGER_HIDDEN_COLLAPSED]).
</description>
</method>
<method name="set_split_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="int">
</argument>
<description>
@@ -42389,7 +46957,7 @@
<members>
<member name="collapsed" type="bool" setter="set_collapsed" getter="is_collapsed" brief="">
</member>
- <member name="dragger_visibility" type="int" setter="set_dragger_visibility" getter="get_dragger_visibility" brief="">
+ <member name="dragger_visibility" type="int" setter="set_dragger_visibility" getter="get_dragger_visibility" brief="" enum="SplitContainer.DraggerVisibility">
</member>
<member name="split_offset" type="int" setter="set_split_offset" getter="get_split_offset" brief="">
</member>
@@ -42528,6 +47096,8 @@
</description>
</method>
<method name="set_centered">
+ <return type="void">
+ </return>
<argument index="0" name="centered" type="bool">
</argument>
<description>
@@ -42535,6 +47105,8 @@
</description>
</method>
<method name="set_flip_h">
+ <return type="void">
+ </return>
<argument index="0" name="flip_h" type="bool">
</argument>
<description>
@@ -42542,6 +47114,8 @@
</description>
</method>
<method name="set_flip_v">
+ <return type="void">
+ </return>
<argument index="0" name="flip_v" type="bool">
</argument>
<description>
@@ -42549,6 +47123,8 @@
</description>
</method>
<method name="set_frame">
+ <return type="void">
+ </return>
<argument index="0" name="frame" type="int">
</argument>
<description>
@@ -42556,6 +47132,8 @@
</description>
</method>
<method name="set_hframes">
+ <return type="void">
+ </return>
<argument index="0" name="hframes" type="int">
</argument>
<description>
@@ -42563,12 +47141,16 @@
</description>
</method>
<method name="set_normal_map">
+ <return type="void">
+ </return>
<argument index="0" name="normal_map" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
@@ -42576,6 +47158,8 @@
</description>
</method>
<method name="set_region">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -42583,12 +47167,16 @@
</description>
</method>
<method name="set_region_filter_clip">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_region_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<description>
@@ -42596,6 +47184,8 @@
</description>
</method>
<method name="set_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
@@ -42603,6 +47193,8 @@
</description>
</method>
<method name="set_vframes">
+ <return type="void">
+ </return>
<argument index="0" name="vframes" type="int">
</argument>
<description>
@@ -42692,36 +47284,48 @@
</description>
</method>
<method name="set_frame">
+ <return type="void">
+ </return>
<argument index="0" name="frame" type="int">
</argument>
<description>
</description>
</method>
<method name="set_hframes">
+ <return type="void">
+ </return>
<argument index="0" name="hframes" type="int">
</argument>
<description>
</description>
</method>
<method name="set_region">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_region_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<description>
</description>
</method>
<method name="set_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_vframes">
+ <return type="void">
+ </return>
<argument index="0" name="vframes" type="int">
</argument>
<description>
@@ -42758,13 +47362,13 @@
</description>
<methods>
<method name="get_alpha_cut_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="SpriteBase3D.AlphaCutMode">
</return>
<description>
</description>
</method>
<method name="get_axis" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Vector3.Axis">
</return>
<description>
</description>
@@ -42772,7 +47376,7 @@
<method name="get_draw_flag" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="flag" type="int">
+ <argument index="0" name="flag" type="int" enum="SpriteBase3D.DrawFlags">
</argument>
<description>
</description>
@@ -42826,25 +47430,33 @@
</description>
</method>
<method name="set_alpha_cut_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="SpriteBase3D.AlphaCutMode">
</argument>
<description>
</description>
</method>
<method name="set_axis">
- <argument index="0" name="axis" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="axis" type="int" enum="Vector3.Axis">
</argument>
<description>
</description>
</method>
<method name="set_centered">
+ <return type="void">
+ </return>
<argument index="0" name="centered" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_draw_flag">
- <argument index="0" name="flag" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="flag" type="int" enum="SpriteBase3D.DrawFlags">
</argument>
<argument index="1" name="enabled" type="bool">
</argument>
@@ -42852,36 +47464,48 @@
</description>
</method>
<method name="set_flip_h">
+ <return type="void">
+ </return>
<argument index="0" name="flip_h" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_flip_v">
+ <return type="void">
+ </return>
<argument index="0" name="flip_v" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_modulate">
+ <return type="void">
+ </return>
<argument index="0" name="modulate" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_offset">
+ <return type="void">
+ </return>
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_opacity">
+ <return type="void">
+ </return>
<argument index="0" name="opacity" type="float">
</argument>
<description>
</description>
</method>
<method name="set_pixel_size">
+ <return type="void">
+ </return>
<argument index="0" name="pixel_size" type="float">
</argument>
<description>
@@ -42889,9 +47513,9 @@
</method>
</methods>
<members>
- <member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" brief="">
+ <member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" brief="" enum="SpriteBase3D.AlphaCutMode">
</member>
- <member name="axis" type="int" setter="set_axis" getter="get_axis" brief="">
+ <member name="axis" type="int" setter="set_axis" getter="get_axis" brief="" enum="Vector3.Axis">
</member>
<member name="centered" type="bool" setter="set_centered" getter="is_centered" brief="">
</member>
@@ -42940,15 +47564,19 @@
</description>
<methods>
<method name="add_animation">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<description>
</description>
</method>
<method name="add_frame">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
- <argument index="1" name="frame" type="Object">
+ <argument index="1" name="frame" type="Texture">
</argument>
<argument index="2" name="atpos" type="int" default="-1">
</argument>
@@ -42956,12 +47584,16 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<description>
</description>
</method>
<method name="clear_all">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -42982,7 +47614,7 @@
</description>
</method>
<method name="get_frame" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<argument index="0" name="anim" type="String">
</argument>
@@ -43008,12 +47640,16 @@
</description>
</method>
<method name="remove_animation">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<description>
</description>
</method>
<method name="remove_frame">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<argument index="1" name="idx" type="int">
@@ -43022,6 +47658,8 @@
</description>
</method>
<method name="rename_animation">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<argument index="1" name="newname" type="String">
@@ -43030,6 +47668,8 @@
</description>
</method>
<method name="set_animation_loop">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<argument index="1" name="loop" type="bool">
@@ -43038,6 +47678,8 @@
</description>
</method>
<method name="set_animation_speed">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<argument index="1" name="speed" type="float">
@@ -43046,11 +47688,13 @@
</description>
</method>
<method name="set_frame">
+ <return type="void">
+ </return>
<argument index="0" name="anim" type="String">
</argument>
<argument index="1" name="idx" type="int">
</argument>
- <argument index="2" name="txt" type="Object">
+ <argument index="2" name="txt" type="Texture">
</argument>
<description>
</description>
@@ -43104,6 +47748,8 @@
</description>
</method>
<method name="set_bounce">
+ <return type="void">
+ </return>
<argument index="0" name="bounce" type="float">
</argument>
<description>
@@ -43111,6 +47757,8 @@
</description>
</method>
<method name="set_constant_angular_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="vel" type="Vector3">
</argument>
<description>
@@ -43118,6 +47766,8 @@
</description>
</method>
<method name="set_constant_linear_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="vel" type="Vector3">
</argument>
<description>
@@ -43125,6 +47775,8 @@
</description>
</method>
<method name="set_friction">
+ <return type="void">
+ </return>
<argument index="0" name="friction" type="float">
</argument>
<description>
@@ -43184,6 +47836,8 @@
</description>
</method>
<method name="set_bounce">
+ <return type="void">
+ </return>
<argument index="0" name="bounce" type="float">
</argument>
<description>
@@ -43191,6 +47845,8 @@
</description>
</method>
<method name="set_constant_angular_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="vel" type="float">
</argument>
<description>
@@ -43198,6 +47854,8 @@
</description>
</method>
<method name="set_constant_linear_velocity">
+ <return type="void">
+ </return>
<argument index="0" name="vel" type="Vector2">
</argument>
<description>
@@ -43205,6 +47863,8 @@
</description>
</method>
<method name="set_friction">
+ <return type="void">
+ </return>
<argument index="0" name="friction" type="float">
</argument>
<description>
@@ -43343,7 +48003,7 @@
<argument index="0" name="bytes" type="int">
</argument>
<description>
- Get an utf8 string with byte-length "bytes" from the stream (this decodes the string sent as utf8).
+ Get a utf8 string with byte-length "bytes" from the stream (this decodes the string sent as utf8).
</description>
</method>
<method name="get_var">
@@ -43361,6 +48021,8 @@
</description>
</method>
<method name="put_16">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43368,6 +48030,8 @@
</description>
</method>
<method name="put_32">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43375,6 +48039,8 @@
</description>
</method>
<method name="put_64">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43382,6 +48048,8 @@
</description>
</method>
<method name="put_8">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43389,7 +48057,7 @@
</description>
</method>
<method name="put_data">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="data" type="PoolByteArray">
</argument>
@@ -43398,6 +48066,8 @@
</description>
</method>
<method name="put_double">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="float">
</argument>
<description>
@@ -43405,6 +48075,8 @@
</description>
</method>
<method name="put_float">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="float">
</argument>
<description>
@@ -43421,6 +48093,8 @@
</description>
</method>
<method name="put_u16">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43428,6 +48102,8 @@
</description>
</method>
<method name="put_u32">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43435,6 +48111,8 @@
</description>
</method>
<method name="put_u64">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43442,6 +48120,8 @@
</description>
</method>
<method name="put_u8">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="int">
</argument>
<description>
@@ -43449,6 +48129,8 @@
</description>
</method>
<method name="put_utf8_string">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="String">
</argument>
<description>
@@ -43456,6 +48138,8 @@
</description>
</method>
<method name="put_var">
+ <return type="void">
+ </return>
<argument index="0" name="val" type="Variant">
</argument>
<description>
@@ -43463,6 +48147,8 @@
</description>
</method>
<method name="set_big_endian">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -43480,6 +48166,8 @@
</description>
<methods>
<method name="clear">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -43508,18 +48196,24 @@
</description>
</method>
<method name="resize">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="int">
</argument>
<description>
</description>
</method>
<method name="seek">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="int">
</argument>
<description>
</description>
</method>
<method name="set_data_array">
+ <return type="void">
+ </return>
<argument index="0" name="data" type="PoolByteArray">
</argument>
<description>
@@ -43538,7 +48232,7 @@
</description>
<methods>
<method name="accept_stream">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="stream" type="StreamPeer">
</argument>
@@ -43546,7 +48240,7 @@
</description>
</method>
<method name="connect_to_stream">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="stream" type="StreamPeer">
</argument>
@@ -43559,12 +48253,14 @@
</description>
</method>
<method name="disconnect_from_stream">
+ <return type="void">
+ </return>
<description>
Disconnect from host.
</description>
</method>
<method name="get_status" qualifiers="const">
- <return type="int">
+ <return type="int" enum="StreamPeerSSL.Status">
</return>
<description>
Return the status of the connection, one of STATUS_* enum.
@@ -43595,7 +48291,7 @@
</description>
<methods>
<method name="connect_to_host">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="host" type="String">
</argument>
@@ -43606,6 +48302,8 @@
</description>
</method>
<method name="disconnect_from_host">
+ <return type="void">
+ </return>
<description>
Disconnect from host.
</description>
@@ -43625,7 +48323,7 @@
</description>
</method>
<method name="get_status" qualifiers="const">
- <return type="int">
+ <return type="int" enum="StreamPeerTCP.Status">
</return>
<description>
Return the status of the connection, one of STATUS_* enum.
@@ -43666,7 +48364,7 @@
</description>
</method>
<method name="load">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
@@ -44032,7 +48730,7 @@
<return type="int">
</return>
<description>
- Convert a string containing an hexadecimal number into an int.
+ Convert a string containing a hexadecimal number into an int.
</description>
</method>
<method name="insert">
@@ -44415,6 +49113,8 @@
</description>
<methods>
<method name="draw" qualifiers="const">
+ <return type="void">
+ </return>
<argument index="0" name="canvas_item" type="RID">
</argument>
<argument index="1" name="rect" type="Rect2">
@@ -44431,7 +49131,7 @@
<method name="get_default_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return the default offset of the margin "margin" (see MARGIN_* enum) of a StyleBox, Controls that draw styleboxes with context inside need to know the margin, so the border of the stylebox is not occluded.
@@ -44440,7 +49140,7 @@
<method name="get_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return the offset of margin "margin" (see MARGIN_* enum).
@@ -44461,7 +49161,9 @@
</description>
</method>
<method name="set_default_margin">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="offset" type="float">
</argument>
@@ -44508,12 +49210,35 @@
</class>
<class name="StyleBoxFlat" inherits="StyleBox" category="Core">
<brief_description>
- Stylebox of a single color.
- </brief_description>
- <description>
- Stylebox of a single color. Displays the stylebox of a single color, alternatively a border with light/dark colors can be assigned.
+ Customizable Stylebox with a given set of parameters. (no texture required)
+ </brief_description>
+ <description>
+ This stylebox can be used to achieve all kinds of looks without the need of a texture. Those properties are customizable:
+ - Color
+ - Border width (individual width for each border)
+ - Rounded corners (individual radius for each corner)
+ - Shadow
+ About corner radius:
+ Setting corner radius to high values is allowed. As soon as corners would overlap the stylebox will switch to a relative system. Example:
+ [codeblock]
+ height = 30
+ corner_radius_top_left = 50
+ corner_raidus_bottom_left = 100
+ [/codeblock]
+ The relative system now would take the 1:2 ratio of the two left corners to calculate the actual corner width. Both corners added will [b]never[/b] be more than the height. Result:
+ [codeblock]
+ corner_radius_top_left: 10
+ corner_raidus_bottom_left: 20
+ [/codeblock]
+
</description>
<methods>
+ <method name="get_aa_size" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_bg_color" qualifiers="const">
<return type="Color">
</return>
@@ -44526,79 +49251,292 @@
<description>
</description>
</method>
- <method name="get_border_size" qualifiers="const">
+ <method name="get_border_color" qualifiers="const">
+ <return type="Color">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_border_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_border_width_min" qualifiers="const">
<return type="int">
</return>
<description>
</description>
</method>
- <method name="get_dark_color" qualifiers="const">
+ <method name="get_corner_detail" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_corner_radius" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="corner" type="int" enum="Corner">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_expand_margin" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_shadow_color" qualifiers="const">
<return type="Color">
</return>
<description>
</description>
</method>
- <method name="get_draw_center" qualifiers="const">
+ <method name="get_shadow_size" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_anti_aliased" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
- <method name="get_light_color" qualifiers="const">
- <return type="Color">
+ <method name="is_draw_center_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_aa_size">
+ <return type="void">
</return>
+ <argument index="0" name="size" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_anti_aliased">
+ <return type="void">
+ </return>
+ <argument index="0" name="anti_aliased" type="bool">
+ </argument>
<description>
</description>
</method>
<method name="set_bg_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_border_blend">
+ <return type="void">
+ </return>
<argument index="0" name="blend" type="bool">
</argument>
<description>
</description>
</method>
- <method name="set_border_size">
- <argument index="0" name="size" type="int">
+ <method name="set_border_color">
+ <return type="void">
+ </return>
+ <argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
- <method name="set_dark_color">
- <argument index="0" name="color" type="Color">
+ <method name="set_border_width">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
+ </argument>
+ <argument index="1" name="width" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_border_width_all">
+ <return type="void">
+ </return>
+ <argument index="0" name="width" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_corner_detail">
+ <return type="void">
+ </return>
+ <argument index="0" name="detail" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_corner_radius">
+ <return type="void">
+ </return>
+ <argument index="0" name="corner" type="int" enum="Corner">
+ </argument>
+ <argument index="1" name="radius" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_corner_radius_all">
+ <return type="void">
+ </return>
+ <argument index="0" name="radius" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_corner_radius_individual">
+ <return type="void">
+ </return>
+ <argument index="0" name="radius_top_left" type="int">
+ </argument>
+ <argument index="1" name="radius_top_right" type="int">
+ </argument>
+ <argument index="2" name="radius_botton_right" type="int">
+ </argument>
+ <argument index="3" name="radius_bottom_left" type="int">
</argument>
<description>
</description>
</method>
<method name="set_draw_center">
- <argument index="0" name="size" type="bool">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_center" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_expand_margin">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
+ </argument>
+ <argument index="1" name="size" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_expand_margin_all">
+ <return type="void">
+ </return>
+ <argument index="0" name="size" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_light_color">
+ <method name="set_expand_margin_individual">
+ <return type="void">
+ </return>
+ <argument index="0" name="size_left" type="float">
+ </argument>
+ <argument index="1" name="size_top" type="float">
+ </argument>
+ <argument index="2" name="size_right" type="float">
+ </argument>
+ <argument index="3" name="size_bottom" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_shadow_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
+ <method name="set_shadow_size">
+ <return type="void">
+ </return>
+ <argument index="0" name="size" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
+ <member name="anti_aliasing" type="bool" setter="set_anti_aliased" getter="is_anti_aliased" brief="">
+ Anti Aliasing draws a small ring around edges. This ring fades to transparent. As a result edges look much smoother. This is only noticable when using rounded corners.
+ </member>
+ <member name="anti_aliasing_size" type="int" setter="set_aa_size" getter="get_aa_size" brief="">
+ This changes the size of the faded ring. Higher values can be used to achieve a "blurry" effect.
+ </member>
<member name="bg_color" type="Color" setter="set_bg_color" getter="get_bg_color" brief="">
+ The background color of the stylebox.
</member>
<member name="border_blend" type="bool" setter="set_border_blend" getter="get_border_blend" brief="">
+ When set to true, the border will fade into the background color.
+ </member>
+ <member name="border_color" type="Color" setter="set_border_color" getter="get_border_color" brief="">
+ Sets the color of the border.
+ </member>
+ <member name="border_width_bottom" type="int" setter="set_border_width" getter="get_border_width" brief="">
+ Border width for the bottom border.
</member>
- <member name="border_size" type="int" setter="set_border_size" getter="get_border_size" brief="">
+ <member name="border_width_left" type="int" setter="set_border_width" getter="get_border_width" brief="">
+ Border width for the left border.
</member>
- <member name="dark_color" type="Color" setter="set_dark_color" getter="get_dark_color" brief="">
+ <member name="border_width_right" type="int" setter="set_border_width" getter="get_border_width" brief="">
+ Border width for the right border.
</member>
- <member name="draw_bg" type="bool" setter="set_draw_center" getter="get_draw_center" brief="">
+ <member name="border_width_top" type="int" setter="set_border_width" getter="get_border_width" brief="">
+ Border width for the top border.
</member>
- <member name="light_color" type="Color" setter="set_light_color" getter="get_light_color" brief="">
+ <member name="corner_detail" type="int" setter="set_corner_detail" getter="get_corner_detail" brief="">
+ This sets the amount of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value you should take the corner radius ([method set_corner_radius]) into account.
+ For corner radius smaller than 10: 4-5 should be enough
+ For corner radius smaller than 30: 8-12 should be enough ...
+ </member>
+ <member name="corner_radius_bottom_left" type="int" setter="set_corner_radius" getter="get_corner_radius" brief="">
+ The corner radius of the bottom left corner. When set to 0 the corner is not rounded.
+ </member>
+ <member name="corner_radius_bottom_right" type="int" setter="set_corner_radius" getter="get_corner_radius" brief="">
+ The corner radius of the bottom right corner. When set to 0 the corner is not rounded.
+ </member>
+ <member name="corner_radius_top_left" type="int" setter="set_corner_radius" getter="get_corner_radius" brief="">
+ The corner radius of the top left corner. When set to 0 the corner is not rounded.
+ </member>
+ <member name="corner_radius_top_right" type="int" setter="set_corner_radius" getter="get_corner_radius" brief="">
+ The corner radius of the top right corner. When set to 0 the corner is not rounded.
+ </member>
+ <member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" brief="">
+ Toggels drawing of the inner part of the stylebox.
+ </member>
+ <member name="expand_margin_bottom" type="float" setter="set_expand_margin" getter="get_expand_margin" brief="">
+ Expands the stylebox outside of the control rect on the bottom edge. Useful in combination with border_width_bottom. To draw a border outside the control rect.
+ </member>
+ <member name="expand_margin_left" type="float" setter="set_expand_margin" getter="get_expand_margin" brief="">
+ Expands the stylebox outside of the control rect on the left edge. Useful in combination with border_width_left. To draw a border outside the control rect.
+ </member>
+ <member name="expand_margin_right" type="float" setter="set_expand_margin" getter="get_expand_margin" brief="">
+ Expands the stylebox outside of the control rect on the right edge. Useful in combination with border_width_right. To draw a border outside the control rect.
+ </member>
+ <member name="expand_margin_top" type="float" setter="set_expand_margin" getter="get_expand_margin" brief="">
+ Expands the stylebox outside of the control rect on the top edge. Useful in combination with border_width_top. To draw a border outside the control rect.
+ </member>
+ <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" brief="">
+ The color of the shadow. (This has no effect when shadow_size < 1)
+ </member>
+ <member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" brief="">
+ The shadow size in pixels.
</member>
</members>
<constants>
@@ -44612,24 +49550,24 @@
Texture Based 3x3 scale style. This stylebox performs a 3x3 scaling of a texture, where only the center cell is fully stretched. This allows for the easy creation of bordered styles.
</description>
<methods>
- <method name="get_draw_center" qualifiers="const">
- <return type="bool">
+ <method name="get_expand_margin_size" qualifiers="const">
+ <return type="float">
</return>
+ <argument index="0" name="margin" type="int" enum="Margin">
+ </argument>
<description>
</description>
</method>
- <method name="get_expand_margin_size" qualifiers="const">
- <return type="float">
+ <method name="get_h_axis_stretch_mode" qualifiers="const">
+ <return type="int" enum="StyleBoxTexture.AxisStretchMode">
</return>
- <argument index="0" name="margin" type="int">
- </argument>
<description>
</description>
</method>
<method name="get_margin_size" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
</description>
@@ -44641,7 +49579,7 @@
</description>
</method>
<method name="get_normal_map" qualifiers="const">
- <return type="Texture">
+ <return type="Resource">
</return>
<description>
</description>
@@ -44653,27 +49591,75 @@
</description>
</method>
<method name="get_texture" qualifiers="const">
- <return type="Texture">
+ <return type="Resource">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_v_axis_stretch_mode" qualifiers="const">
+ <return type="int" enum="StyleBoxTexture.AxisStretchMode">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_draw_center_enabled" qualifiers="const">
+ <return type="bool">
</return>
<description>
</description>
</method>
<method name="set_draw_center">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
+ <method name="set_expand_margin_all">
+ <return type="void">
+ </return>
+ <argument index="0" name="size" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_expand_margin_individual">
+ <return type="void">
+ </return>
+ <argument index="0" name="size_left" type="float">
+ </argument>
+ <argument index="1" name="size_top" type="float">
+ </argument>
+ <argument index="2" name="size_right" type="float">
+ </argument>
+ <argument index="3" name="size_bottom" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_expand_margin_size">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="size" type="float">
</argument>
<description>
</description>
</method>
+ <method name="set_h_axis_stretch_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="StyleBoxTexture.AxisStretchMode">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_margin_size">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<argument index="1" name="size" type="float">
</argument>
@@ -44681,32 +49667,52 @@
</description>
</method>
<method name="set_modulate">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
<method name="set_normal_map">
- <argument index="0" name="normal_map" type="Texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="normal_map" type="Resource">
</argument>
<description>
</description>
</method>
<method name="set_region_rect">
+ <return type="void">
+ </return>
<argument index="0" name="region" type="Rect2">
</argument>
<description>
</description>
</method>
<method name="set_texture">
- <argument index="0" name="texture" type="Texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Resource">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_v_axis_stretch_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="StyleBoxTexture.AxisStretchMode">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="draw_center" type="bool" setter="set_draw_center" getter="get_draw_center" brief="">
+ <member name="axis_stretch_horizontal" type="int" setter="set_h_axis_stretch_mode" getter="get_h_axis_stretch_mode" brief="" enum="StyleBoxTexture.AxisStretchMode">
+ </member>
+ <member name="axis_stretch_vertical" type="int" setter="set_v_axis_stretch_mode" getter="get_v_axis_stretch_mode" brief="" enum="StyleBoxTexture.AxisStretchMode">
+ </member>
+ <member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" brief="">
</member>
<member name="expand_margin_bottom" type="float" setter="set_expand_margin_size" getter="get_expand_margin_size" brief="">
</member>
@@ -44726,11 +49732,11 @@
</member>
<member name="modulate_color" type="Color" setter="set_modulate" getter="get_modulate" brief="">
</member>
- <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" brief="">
+ <member name="normal_map" type="Resource" setter="set_normal_map" getter="get_normal_map" brief="">
</member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" brief="">
</member>
- <member name="texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
+ <member name="texture" type="Resource" setter="set_texture" getter="get_texture" brief="">
</member>
</members>
<signals>
@@ -44740,6 +49746,12 @@
</signal>
</signals>
<constants>
+ <constant name="AXIS_STRETCH_MODE_STRETCH" value="0">
+ </constant>
+ <constant name="AXIS_STRETCH_MODE_TILE" value="1">
+ </constant>
+ <constant name="AXIS_STRETCH_MODE_TILE_FIT" value="2">
+ </constant>
</constants>
</class>
<class name="SurfaceTool" inherits="Reference" category="Core">
@@ -44760,6 +49772,8 @@
</description>
<methods>
<method name="add_bones">
+ <return type="void">
+ </return>
<argument index="0" name="bones" type="PoolIntArray">
</argument>
<description>
@@ -44767,6 +49781,8 @@
</description>
</method>
<method name="add_color">
+ <return type="void">
+ </return>
<argument index="0" name="color" type="Color">
</argument>
<description>
@@ -44774,6 +49790,8 @@
</description>
</method>
<method name="add_index">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<description>
@@ -44781,6 +49799,8 @@
</description>
</method>
<method name="add_normal">
+ <return type="void">
+ </return>
<argument index="0" name="normal" type="Vector3">
</argument>
<description>
@@ -44788,6 +49808,8 @@
</description>
</method>
<method name="add_smooth_group">
+ <return type="void">
+ </return>
<argument index="0" name="smooth" type="bool">
</argument>
<description>
@@ -44795,30 +49817,44 @@
</description>
</method>
<method name="add_tangent">
+ <return type="void">
+ </return>
<argument index="0" name="tangent" type="Plane">
</argument>
<description>
Specify a Tangent for the next Vertex to use.
</description>
</method>
+ <method name="add_to_format">
+ <return type="void">
+ </return>
+ <argument index="0" name="flags" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="add_triangle_fan">
+ <return type="void">
+ </return>
<argument index="0" name="vertexes" type="PoolVector3Array">
</argument>
- <argument index="1" name="uvs" type="PoolVector2Array" default="PoolVector2Array([])">
+ <argument index="1" name="uvs" type="PoolVector2Array" default="PoolVector2Array( )">
</argument>
- <argument index="2" name="colors" type="PoolColorArray" default="PoolColorArray([PoolColorArray])">
+ <argument index="2" name="colors" type="PoolColorArray" default="PoolColorArray( )">
</argument>
- <argument index="3" name="uv2s" type="PoolVector2Array" default="PoolVector2Array([])">
+ <argument index="3" name="uv2s" type="PoolVector2Array" default="PoolVector2Array( )">
</argument>
- <argument index="4" name="normals" type="PoolVector3Array" default="PoolVector3Array([])">
+ <argument index="4" name="normals" type="PoolVector3Array" default="PoolVector3Array( )">
</argument>
- <argument index="5" name="tangents" type="Array" default="[]">
+ <argument index="5" name="tangents" type="Array" default="[ ]">
</argument>
<description>
Insert a triangle fan made of array data into [Mesh] being constructed.
</description>
</method>
<method name="add_uv">
+ <return type="void">
+ </return>
<argument index="0" name="uv" type="Vector2">
</argument>
<description>
@@ -44826,6 +49862,8 @@
</description>
</method>
<method name="add_uv2">
+ <return type="void">
+ </return>
<argument index="0" name="uv2" type="Vector2">
</argument>
<description>
@@ -44833,6 +49871,8 @@
</description>
</method>
<method name="add_vertex">
+ <return type="void">
+ </return>
<argument index="0" name="vertex" type="Vector3">
</argument>
<description>
@@ -44840,49 +49880,91 @@
</description>
</method>
<method name="add_weights">
+ <return type="void">
+ </return>
<argument index="0" name="weights" type="PoolRealArray">
</argument>
<description>
Specify weight value for next Vertex to use.
</description>
</method>
+ <method name="append_from">
+ <return type="void">
+ </return>
+ <argument index="0" name="existing" type="Mesh">
+ </argument>
+ <argument index="1" name="surface" type="int">
+ </argument>
+ <argument index="2" name="transform" type="Transform">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="begin">
- <argument index="0" name="primitive" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="primitive" type="int" enum="Mesh.PrimitiveType">
</argument>
<description>
Called before adding any Vertices. Takes the primitive type as an argument (e.g. Mesh.PRIMITIVE_TRIANGLES).
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear all information passed into the surface tool so far.
</description>
</method>
<method name="commit">
- <return type="Mesh">
+ <return type="ArrayMesh">
+ </return>
+ <argument index="0" name="existing" type="ArrayMesh" default="null">
+ </argument>
+ <description>
+ Returns a constructed [ArrayMesh] from current information passed in. If an existing [ArrayMesh] is passed in as an argument, will add an extra surface to the existing [ArrayMesh].
+ </description>
+ </method>
+ <method name="create_from">
+ <return type="void">
</return>
- <argument index="0" name="existing" type="Mesh" default="NULL">
+ <argument index="0" name="existing" type="Mesh">
+ </argument>
+ <argument index="1" name="surface" type="int">
</argument>
<description>
- Returns a constructed [Mesh] from current information passed in. If an existing [Mesh] is passed in as an argument, will add an extra surface to the existing [Mesh].
</description>
</method>
<method name="deindex">
+ <return type="void">
+ </return>
<description>
Removes index array by expanding Vertex array.
</description>
</method>
<method name="generate_normals">
+ <return type="void">
+ </return>
<description>
Generates normals from Vertices so you do not have to do it manually.
</description>
</method>
+ <method name="generate_tangents">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="index">
+ <return type="void">
+ </return>
<description>
Shrinks Vertex array by creating an index array. Avoids reusing Vertices.
</description>
</method>
<method name="set_material">
+ <return type="void">
+ </return>
<argument index="0" name="material" type="Material">
</argument>
<description>
@@ -44909,7 +49991,7 @@
</description>
</method>
<method name="listen">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="port" type="int">
</argument>
@@ -44923,12 +50005,14 @@
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
Stop listening.
</description>
</method>
<method name="take_connection">
- <return type="Object">
+ <return type="StreamPeerTCP">
</return>
<description>
If a connection is available, return a StreamPeerTCP with the connection/
@@ -44981,7 +50065,7 @@
</description>
</method>
<method name="get_tab_align" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TabContainer.TabAlign">
</return>
<description>
Return tab alignment, from the ALIGN_* enum.
@@ -45029,6 +50113,8 @@
</description>
</method>
<method name="set_current_tab">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<description>
@@ -45036,19 +50122,25 @@
</description>
</method>
<method name="set_popup">
- <argument index="0" name="popup" type="Popup">
+ <return type="void">
+ </return>
+ <argument index="0" name="popup" type="Node">
</argument>
<description>
</description>
</method>
<method name="set_tab_align">
- <argument index="0" name="align" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="align" type="int" enum="TabContainer.TabAlign">
</argument>
<description>
Set tab alignment, from the ALIGN_* enum. Moves tabs to the left, right or center.
</description>
</method>
<method name="set_tab_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<argument index="1" name="disabled" type="bool">
@@ -45057,6 +50149,8 @@
</description>
</method>
<method name="set_tab_icon">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<argument index="1" name="icon" type="Texture">
@@ -45066,6 +50160,8 @@
</description>
</method>
<method name="set_tab_title">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<argument index="1" name="title" type="String">
@@ -45075,6 +50171,8 @@
</description>
</method>
<method name="set_tabs_visible">
+ <return type="void">
+ </return>
<argument index="0" name="visible" type="bool">
</argument>
<description>
@@ -45085,7 +50183,7 @@
<members>
<member name="current_tab" type="int" setter="set_current_tab" getter="get_current_tab" brief="">
</member>
- <member name="tab_align" type="int" setter="set_tab_align" getter="get_tab_align" brief="">
+ <member name="tab_align" type="int" setter="set_tab_align" getter="get_tab_align" brief="" enum="TabContainer.TabAlign">
</member>
<member name="tabs_visible" type="bool" setter="set_tabs_visible" getter="are_tabs_visible" brief="">
</member>
@@ -45160,14 +50258,18 @@
</description>
<methods>
<method name="add_tab">
- <argument index="0" name="title" type="String">
+ <return type="void">
+ </return>
+ <argument index="0" name="title" type="String" default="&quot;&quot;">
</argument>
- <argument index="1" name="icon" type="Texture">
+ <argument index="1" name="icon" type="Texture" default="null">
</argument>
<description>
</description>
</method>
<method name="ensure_tab_visible">
+ <return type="void">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -45180,7 +50282,13 @@
</description>
</method>
<method name="get_tab_align" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Tabs.TabAlign">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_tab_close_display_policy" qualifiers="const">
+ <return type="int" enum="Tabs.CloseButtonDisplayPolicy">
</return>
<description>
</description>
@@ -45207,7 +50315,7 @@
<description>
</description>
</method>
- <method name="get_tab_rect">
+ <method name="get_tab_rect" qualifiers="const">
<return type="Rect2">
</return>
<argument index="0" name="tab_idx" type="int">
@@ -45225,6 +50333,8 @@
</description>
</method>
<method name="move_tab">
+ <return type="void">
+ </return>
<argument index="0" name="from" type="int">
</argument>
<argument index="1" name="to" type="int">
@@ -45234,24 +50344,40 @@
</description>
</method>
<method name="remove_tab">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<description>
</description>
</method>
<method name="set_current_tab">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<description>
</description>
</method>
<method name="set_tab_align">
- <argument index="0" name="align" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="align" type="int" enum="Tabs.TabAlign">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_tab_close_display_policy">
+ <return type="void">
+ </return>
+ <argument index="0" name="policy" type="int" enum="Tabs.CloseButtonDisplayPolicy">
</argument>
<description>
</description>
</method>
<method name="set_tab_disabled">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<argument index="1" name="disabled" type="bool">
@@ -45260,6 +50386,8 @@
</description>
</method>
<method name="set_tab_icon">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<argument index="1" name="icon" type="Texture">
@@ -45268,6 +50396,8 @@
</description>
</method>
<method name="set_tab_title">
+ <return type="void">
+ </return>
<argument index="0" name="tab_idx" type="int">
</argument>
<argument index="1" name="title" type="String">
@@ -45279,6 +50409,8 @@
<members>
<member name="current_tab" type="int" setter="set_current_tab" getter="get_current_tab" brief="">
</member>
+ <member name="tab_close_display_policy" type="int" setter="set_tab_close_display_policy" getter="get_tab_close_display_policy" brief="" enum="Tabs.CloseButtonDisplayPolicy">
+ </member>
</members>
<signals>
<signal name="reposition_active_tab_request">
@@ -45299,6 +50431,12 @@
<description>
</description>
</signal>
+ <signal name="tab_clicked">
+ <argument index="0" name="tab" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="tab_close">
<argument index="0" name="tab" type="int">
</argument>
@@ -45319,12 +50457,16 @@
</constant>
<constant name="ALIGN_RIGHT" value="2">
</constant>
+ <constant name="ALIGN_MAX" value="3">
+ </constant>
<constant name="CLOSE_BUTTON_SHOW_ACTIVE_ONLY" value="1">
</constant>
<constant name="CLOSE_BUTTON_SHOW_ALWAYS" value="2">
</constant>
<constant name="CLOSE_BUTTON_SHOW_NEVER" value="0">
</constant>
+ <constant name="CLOSE_BUTTON_MAX" value="3">
+ </constant>
</constants>
<theme_items>
<theme_item name="button" type="StyleBox">
@@ -45374,6 +50516,8 @@
</description>
<methods>
<method name="add_color_region">
+ <return type="void">
+ </return>
<argument index="0" name="begin_key" type="String">
</argument>
<argument index="1" name="end_key" type="String">
@@ -45387,6 +50531,8 @@
</description>
</method>
<method name="add_keyword_color">
+ <return type="void">
+ </return>
<argument index="0" name="keyword" type="String">
</argument>
<argument index="1" name="color" type="Color">
@@ -45396,16 +50542,22 @@
</description>
</method>
<method name="clear_colors">
+ <return type="void">
+ </return>
<description>
Clear all the syntax coloring information.
</description>
</method>
<method name="clear_undo_history">
+ <return type="void">
+ </return>
<description>
Clear the undo history.
</description>
</method>
<method name="copy">
+ <return type="void">
+ </return>
<description>
Copy the current selection.
</description>
@@ -45446,6 +50598,8 @@
</description>
</method>
<method name="cursor_set_blink_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -45453,6 +50607,8 @@
</description>
</method>
<method name="cursor_set_blink_speed">
+ <return type="void">
+ </return>
<argument index="0" name="blink_speed" type="float">
</argument>
<description>
@@ -45460,6 +50616,8 @@
</description>
</method>
<method name="cursor_set_block_mode">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -45467,6 +50625,8 @@
</description>
</method>
<method name="cursor_set_column">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="adjust_viewport" type="bool" default="true">
@@ -45475,6 +50635,8 @@
</description>
</method>
<method name="cursor_set_line">
+ <return type="void">
+ </return>
<argument index="0" name="line" type="int">
</argument>
<argument index="1" name="adjust_viewport" type="bool" default="true">
@@ -45483,6 +50645,8 @@
</description>
</method>
<method name="cut">
+ <return type="void">
+ </return>
<description>
Cut the current selection.
</description>
@@ -45551,6 +50715,12 @@
Return the whole text.
</description>
</method>
+ <method name="get_v_scroll_speed" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_word_under_cursor" qualifiers="const">
<return type="String">
</return>
@@ -45558,6 +50728,8 @@
</description>
</method>
<method name="insert_text_at_cursor">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
@@ -45585,6 +50757,12 @@
Returns true if line numbers are enabled.
</description>
</method>
+ <method name="is_smooth_scroll_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_syntax_coloring_enabled" qualifiers="const">
<return type="bool">
</return>
@@ -45593,17 +50771,23 @@
</description>
</method>
<method name="menu_option">
- <argument index="0" name="arg0" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="option" type="int">
</argument>
<description>
</description>
</method>
<method name="paste">
+ <return type="void">
+ </return>
<description>
Paste the current selection.
</description>
</method>
<method name="redo">
+ <return type="void">
+ </return>
<description>
Perform redo operation.
</description>
@@ -45611,19 +50795,21 @@
<method name="search" qualifiers="const">
<return type="PoolIntArray">
</return>
- <argument index="0" name="flags" type="String">
+ <argument index="0" name="key" type="String">
</argument>
- <argument index="1" name="from_line" type="int">
+ <argument index="1" name="flags" type="int">
</argument>
- <argument index="2" name="from_column" type="int">
+ <argument index="2" name="from_line" type="int">
</argument>
- <argument index="3" name="to_line" type="int">
+ <argument index="3" name="from_column" type="int">
</argument>
<description>
Perform a search inside the text. Search flags can be specified in the SEARCH_* enum.
</description>
</method>
<method name="select">
+ <return type="void">
+ </return>
<argument index="0" name="from_line" type="int">
</argument>
<argument index="1" name="from_column" type="int">
@@ -45637,11 +50823,15 @@
</description>
</method>
<method name="select_all">
+ <return type="void">
+ </return>
<description>
Select all the text.
</description>
</method>
<method name="set_highlight_all_occurrences">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -45649,6 +50839,8 @@
</description>
</method>
<method name="set_max_chars">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -45656,6 +50848,8 @@
</description>
</method>
<method name="set_readonly">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -45663,13 +50857,25 @@
</description>
</method>
<method name="set_show_line_numbers">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
Set to enable showing line numbers.
</description>
</method>
+ <method name="set_smooth_scroll_enable">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_syntax_coloring">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -45677,13 +50883,25 @@
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="text" type="String">
</argument>
<description>
Set the entire text.
</description>
</method>
+ <method name="set_v_scroll_speed">
+ <return type="void">
+ </return>
+ <argument index="0" name="speed" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_wrap">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -45691,6 +50909,8 @@
</description>
</method>
<method name="undo">
+ <return type="void">
+ </return>
<description>
Perform undo operation.
</description>
@@ -45707,8 +50927,12 @@
</member>
<member name="show_line_numbers" type="bool" setter="set_show_line_numbers" getter="is_show_line_numbers_enabled" brief="">
</member>
+ <member name="smooth_scrolling" type="bool" setter="set_smooth_scroll_enable" getter="is_smooth_scroll_enabled" brief="">
+ </member>
<member name="syntax_highlighting" type="bool" setter="set_syntax_coloring" getter="is_syntax_coloring_enabled" brief="">
</member>
+ <member name="v_scroll_speed" type="float" setter="set_v_scroll_speed" getter="get_v_scroll_speed" brief="">
+ </member>
</members>
<signals>
<signal name="breakpoint_toggled">
@@ -45840,53 +51064,65 @@
</description>
<methods>
<method name="draw" qualifiers="const">
+ <return type="void">
+ </return>
<argument index="0" name="canvas_item" type="RID">
</argument>
<argument index="1" name="pos" type="Vector2">
</argument>
- <argument index="2" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="2" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="3" name="transpose" type="bool" default="false">
</argument>
- <argument index="4" name="normal_map" type="Texture" default="NULL">
+ <argument index="4" name="normal_map" type="Texture" default="null">
</argument>
<description>
</description>
</method>
<method name="draw_rect" qualifiers="const">
+ <return type="void">
+ </return>
<argument index="0" name="canvas_item" type="RID">
</argument>
<argument index="1" name="rect" type="Rect2">
</argument>
<argument index="2" name="tile" type="bool">
</argument>
- <argument index="3" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
- <argument index="5" name="normal_map" type="Texture" default="NULL">
+ <argument index="5" name="normal_map" type="Texture" default="null">
</argument>
<description>
</description>
</method>
<method name="draw_rect_region" qualifiers="const">
+ <return type="void">
+ </return>
<argument index="0" name="canvas_item" type="RID">
</argument>
<argument index="1" name="rect" type="Rect2">
</argument>
<argument index="2" name="src_rect" type="Rect2">
</argument>
- <argument index="3" name="modulate" type="Color" default="Color(1,1,1,1)">
+ <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
- <argument index="5" name="normal_map" type="Texture" default="NULL">
+ <argument index="5" name="normal_map" type="Texture" default="null">
</argument>
<argument index="6" name="clip_uv" type="bool" default="true">
</argument>
<description>
</description>
</method>
+ <method name="get_data" qualifiers="const">
+ <return type="Image">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_flags" qualifiers="const">
<return type="int">
</return>
@@ -45922,6 +51158,8 @@
</description>
</method>
<method name="set_flags">
+ <return type="void">
+ </return>
<argument index="0" name="flags" type="int">
</argument>
<description>
@@ -46005,55 +51243,71 @@
</description>
</method>
<method name="get_stretch_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TextureButton.StretchMode">
</return>
<description>
</description>
</method>
<method name="set_click_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="BitMap">
</argument>
<description>
</description>
</method>
<method name="set_disabled_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_expand">
+ <return type="void">
+ </return>
<argument index="0" name="p_expand" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_focused_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_hover_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_normal_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_pressed_texture">
+ <return type="void">
+ </return>
<argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_stretch_mode">
- <argument index="0" name="p_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="p_mode" type="int" enum="TextureButton.StretchMode">
</argument>
<description>
</description>
@@ -46062,7 +51316,7 @@
<members>
<member name="expand" type="bool" setter="set_expand" getter="get_expand" brief="">
</member>
- <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" brief="">
+ <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" brief="" enum="TextureButton.StretchMode">
</member>
<member name="texture_click_mask" type="BitMap" setter="set_click_mask" getter="get_click_mask" brief="">
</member>
@@ -46114,7 +51368,7 @@
<description>
</description>
</method>
- <method name="get_nine_patch_stretch">
+ <method name="get_nine_patch_stretch" qualifiers="const">
<return type="bool">
</return>
<description>
@@ -46122,13 +51376,13 @@
</description>
</method>
<method name="get_over_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
</method>
<method name="get_progress_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
@@ -46148,31 +51402,37 @@
<method name="get_stretch_margin" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="margin" type="int">
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return nine-patch texture offset for a given margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM).
</description>
</method>
<method name="get_under_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
</method>
<method name="set_fill_degrees">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="float">
</argument>
<description>
</description>
</method>
<method name="set_fill_mode">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="int">
</argument>
<description>
</description>
</method>
<method name="set_nine_patch_stretch">
+ <return type="void">
+ </return>
<argument index="0" name="stretch" type="bool">
</argument>
<description>
@@ -46180,40 +51440,52 @@
</description>
</method>
<method name="set_over_texture">
- <argument index="0" name="tex" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="tex" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_progress_texture">
- <argument index="0" name="tex" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="tex" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_radial_center_offset">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_radial_initial_angle">
+ <return type="void">
+ </return>
<argument index="0" name="mode" type="float">
</argument>
<description>
</description>
</method>
<method name="set_stretch_margin">
- <argument index="0" name="margin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="margin" type="int" enum="Margin">
</argument>
- <argument index="1" name="size" type="int">
+ <argument index="1" name="value" type="int">
</argument>
<description>
Set nine-patch texture offset for a given margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM).
</description>
</method>
<method name="set_under_texture">
- <argument index="0" name="tex" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="tex" type="Texture">
</argument>
<description>
</description>
@@ -46222,27 +51494,27 @@
<members>
<member name="fill_mode" type="int" setter="set_fill_mode" getter="get_fill_mode" brief="">
</member>
+ <member name="nine_patch_stretch" type="bool" setter="set_nine_patch_stretch" getter="get_nine_patch_stretch" brief="">
+ </member>
<member name="radial_center_offset" type="Vector2" setter="set_radial_center_offset" getter="get_radial_center_offset" brief="">
</member>
<member name="radial_fill_degrees" type="float" setter="set_fill_degrees" getter="get_fill_degrees" brief="">
</member>
<member name="radial_initial_angle" type="float" setter="set_radial_initial_angle" getter="get_radial_initial_angle" brief="">
</member>
- <member name="texture_over" type="Texture" setter="set_over_texture" getter="get_over_texture" brief="">
- </member>
- <member name="texture_progress" type="Texture" setter="set_progress_texture" getter="get_progress_texture" brief="">
- </member>
- <member name="texture_under" type="Texture" setter="set_under_texture" getter="get_under_texture" brief="">
- </member>
- <member name="nine_patch_stretch" type="bool" setter="set_nine_patch_stretch" getter="get_nine_patch_stretch" brief="">
+ <member name="stretch_margin_bottom" type="int" setter="set_stretch_margin" getter="get_stretch_margin" brief="">
</member>
<member name="stretch_margin_left" type="int" setter="set_stretch_margin" getter="get_stretch_margin" brief="">
</member>
+ <member name="stretch_margin_right" type="int" setter="set_stretch_margin" getter="get_stretch_margin" brief="">
+ </member>
<member name="stretch_margin_top" type="int" setter="set_stretch_margin" getter="get_stretch_margin" brief="">
</member>
- <member name="stretch_margin_right" type="int" setter="set_stretch_margin" getter="get_stretch_margin" brief="">
+ <member name="texture_over" type="Texture" setter="set_over_texture" getter="get_over_texture" brief="">
</member>
- <member name="stretch_margin_bottom" type="int" setter="set_stretch_margin" getter="get_stretch_margin" brief="">
+ <member name="texture_progress" type="Texture" setter="set_progress_texture" getter="get_progress_texture" brief="">
+ </member>
+ <member name="texture_under" type="Texture" setter="set_under_texture" getter="get_under_texture" brief="">
</member>
</members>
<constants>
@@ -46269,13 +51541,13 @@
</description>
<methods>
<method name="get_stretch_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TextureRect.StretchMode">
</return>
<description>
</description>
</method>
<method name="get_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
@@ -46287,19 +51559,25 @@
</description>
</method>
<method name="set_expand">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_stretch_mode">
- <argument index="0" name="stretch_mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="stretch_mode" type="int" enum="TextureRect.StretchMode">
</argument>
<description>
</description>
</method>
<method name="set_texture">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
@@ -46308,7 +51586,7 @@
<members>
<member name="expand" type="bool" setter="set_expand" getter="has_expand" brief="">
</member>
- <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" brief="">
+ <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" brief="" enum="TextureRect.StretchMode">
</member>
<member name="texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
@@ -46342,6 +51620,8 @@
</description>
<methods>
<method name="clear_color">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46350,6 +51630,8 @@
</description>
</method>
<method name="clear_constant">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46358,6 +51640,8 @@
</description>
</method>
<method name="clear_font">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46366,6 +51650,8 @@
</description>
</method>
<method name="clear_icon">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46374,6 +51660,8 @@
</description>
</method>
<method name="clear_stylebox">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46382,6 +51670,8 @@
</description>
</method>
<method name="copy_default_theme">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -46422,7 +51712,7 @@
</description>
</method>
<method name="get_default_font" qualifiers="const">
- <return type="Object">
+ <return type="Font">
</return>
<description>
</description>
@@ -46546,6 +51836,8 @@
</description>
</method>
<method name="set_color">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46556,6 +51848,8 @@
</description>
</method>
<method name="set_constant">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46566,12 +51860,16 @@
</description>
</method>
<method name="set_default_font">
- <argument index="0" name="font" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="font" type="Font">
</argument>
<description>
</description>
</method>
<method name="set_font">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46582,6 +51880,8 @@
</description>
</method>
<method name="set_icon">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46592,6 +51892,8 @@
</description>
</method>
<method name="set_stylebox">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="type" type="String">
@@ -46632,13 +51934,13 @@
</description>
</method>
<method name="start">
- <return type="Error">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="instance" type="Object">
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="userdata" type="Variant" default="NULL">
+ <argument index="2" name="userdata" type="Variant" default="null">
</argument>
<argument index="3" name="priority" type="int" default="1">
</argument>
@@ -46674,6 +51976,8 @@
</description>
<methods>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear all cells.
</description>
@@ -46778,14 +52082,14 @@
</description>
</method>
<method name="get_half_offset" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TileMap.HalfOffset">
</return>
<description>
Return the current half offset configuration.
</description>
</method>
<method name="get_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TileMap.Mode">
</return>
<description>
Return the orientation mode.
@@ -46805,7 +52109,7 @@
</description>
</method>
<method name="get_tile_origin" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TileMap.TileOrigin">
</return>
<description>
Return the tile origin configuration.
@@ -46825,6 +52129,14 @@
Return an array of all cells containing a tile from the tileset (i.e. a tile index different from -1).
</description>
</method>
+ <method name="get_used_cells_by_id" qualifiers="const">
+ <return type="Array">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_used_rect">
<return type="Rect2">
</return>
@@ -46884,6 +52196,8 @@
</description>
</method>
<method name="set_cell">
+ <return type="void">
+ </return>
<argument index="0" name="x" type="int">
</argument>
<argument index="1" name="y" type="int">
@@ -46903,6 +52217,8 @@
</description>
</method>
<method name="set_cell_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
@@ -46910,6 +52226,8 @@
</description>
</method>
<method name="set_cellv">
+ <return type="void">
+ </return>
<argument index="0" name="pos" type="Vector2">
</argument>
<argument index="1" name="tile" type="int">
@@ -46927,6 +52245,8 @@
</description>
</method>
<method name="set_center_x">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -46934,6 +52254,8 @@
</description>
</method>
<method name="set_center_y">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -46941,6 +52263,8 @@
</description>
</method>
<method name="set_collision_bounce">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="float">
</argument>
<description>
@@ -46948,6 +52272,8 @@
</description>
</method>
<method name="set_collision_friction">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="float">
</argument>
<description>
@@ -46955,6 +52281,8 @@
</description>
</method>
<method name="set_collision_layer">
+ <return type="void">
+ </return>
<argument index="0" name="layer" type="int">
</argument>
<description>
@@ -46963,6 +52291,8 @@
</description>
</method>
<method name="set_collision_layer_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -46971,6 +52301,8 @@
</description>
</method>
<method name="set_collision_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
@@ -46979,6 +52311,8 @@
</description>
</method>
<method name="set_collision_mask_bit">
+ <return type="void">
+ </return>
<argument index="0" name="bit" type="int">
</argument>
<argument index="1" name="value" type="bool">
@@ -46987,6 +52321,8 @@
</description>
</method>
<method name="set_collision_use_kinematic">
+ <return type="void">
+ </return>
<argument index="0" name="use_kinematic" type="bool">
</argument>
<description>
@@ -46994,6 +52330,8 @@
</description>
</method>
<method name="set_custom_transform">
+ <return type="void">
+ </return>
<argument index="0" name="custom_transform" type="Transform2D">
</argument>
<description>
@@ -47001,27 +52339,35 @@
</description>
</method>
<method name="set_half_offset">
- <argument index="0" name="half_offset" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="half_offset" type="int" enum="TileMap.HalfOffset">
</argument>
<description>
- Set an half offset on the X coordinate, Y coordinate, or none (use HALF_OFFSET_* constants as argument).
+ Set a half offset on the X coordinate, Y coordinate, or none (use HALF_OFFSET_* constants as argument).
Half offset sets every other tile off by a half tile size in the specified direction.
</description>
</method>
<method name="set_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="TileMap.Mode">
</argument>
<description>
Set the orientation mode as square, isometric or custom (use MODE_* constants as argument).
</description>
</method>
<method name="set_occluder_light_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
</description>
</method>
<method name="set_quadrant_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="int">
</argument>
<description>
@@ -47030,13 +52376,17 @@
</description>
</method>
<method name="set_tile_origin">
- <argument index="0" name="origin" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="origin" type="int" enum="TileMap.TileOrigin">
</argument>
<description>
Set the tile origin to the tile center or its top-left corner (use TILE_ORIGIN_* constants as argument).
</description>
</method>
<method name="set_tileset">
+ <return type="void">
+ </return>
<argument index="0" name="tileset" type="TileSet">
</argument>
<description>
@@ -47044,6 +52394,8 @@
</description>
</method>
<method name="set_y_sort_mode">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -47064,13 +52416,13 @@
<members>
<member name="cell_custom_transform" type="Transform2D" setter="set_custom_transform" getter="get_custom_transform" brief="">
</member>
- <member name="cell_half_offset" type="int" setter="set_half_offset" getter="get_half_offset" brief="">
+ <member name="cell_half_offset" type="int" setter="set_half_offset" getter="get_half_offset" brief="" enum="TileMap.HalfOffset">
</member>
<member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" brief="">
</member>
<member name="cell_size" type="Vector2" setter="set_cell_size" getter="get_cell_size" brief="">
</member>
- <member name="cell_tile_origin" type="int" setter="set_tile_origin" getter="get_tile_origin" brief="">
+ <member name="cell_tile_origin" type="int" setter="set_tile_origin" getter="get_tile_origin" brief="" enum="TileMap.TileOrigin">
</member>
<member name="cell_y_sort" type="bool" setter="set_y_sort_mode" getter="is_y_sort_mode_enabled" brief="">
</member>
@@ -47084,11 +52436,11 @@
</member>
<member name="collision_use_kinematic" type="bool" setter="set_collision_use_kinematic" getter="get_collision_use_kinematic" brief="">
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="TileMap.Mode">
</member>
<member name="occluder_light_mask" type="int" setter="set_occluder_light_mask" getter="get_occluder_light_mask" brief="">
</member>
- <member name="tile_data" type="Object" setter="_set_tile_data" getter="_get_tile_data" brief="">
+ <member name="tile_data" type="PoolIntArray" setter="_set_tile_data" getter="_get_tile_data" brief="">
</member>
<member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset" brief="">
</member>
@@ -47101,7 +52453,7 @@
</signal>
</signals>
<constants>
- <constant name="INVALID_CELL" value="-1">
+ <constant name="INVALID_CELL" value="-1" enum="">
Returned when a cell doesn't exist.
</constant>
<constant name="MODE_SQUARE" value="0">
@@ -47142,11 +52494,15 @@
</description>
<methods>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear all tiles.
</description>
</method>
<method name="create_tile">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
@@ -47177,6 +52533,8 @@
</description>
</method>
<method name="remove_tile">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<description>
@@ -47184,6 +52542,8 @@
</description>
</method>
<method name="tile_add_shape">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="shape" type="Shape2D">
@@ -47332,6 +52692,8 @@
</description>
</method>
<method name="tile_set_light_occluder">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="light_occluder" type="OccluderPolygon2D">
@@ -47341,6 +52703,8 @@
</description>
</method>
<method name="tile_set_material">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="material" type="ShaderMaterial">
@@ -47350,6 +52714,8 @@
</description>
</method>
<method name="tile_set_name">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="name" type="String">
@@ -47359,6 +52725,8 @@
</description>
</method>
<method name="tile_set_navigation_polygon">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="navigation_polygon" type="NavigationPolygon">
@@ -47368,6 +52736,8 @@
</description>
</method>
<method name="tile_set_navigation_polygon_offset">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="navigation_polygon_offset" type="Vector2">
@@ -47377,6 +52747,8 @@
</description>
</method>
<method name="tile_set_normal_map">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="normal_map" type="Texture">
@@ -47385,6 +52757,8 @@
</description>
</method>
<method name="tile_set_occluder_offset">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="occluder_offset" type="Vector2">
@@ -47394,6 +52768,8 @@
</description>
</method>
<method name="tile_set_region">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="region" type="Rect2">
@@ -47403,6 +52779,8 @@
</description>
</method>
<method name="tile_set_shape">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="shape_id" type="int">
@@ -47413,6 +52791,8 @@
</description>
</method>
<method name="tile_set_shape_one_way">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="shape_id" type="int">
@@ -47423,6 +52803,8 @@
</description>
</method>
<method name="tile_set_shape_transform">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="shape_id" type="int">
@@ -47433,6 +52815,8 @@
</description>
</method>
<method name="tile_set_shapes">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="shapes" type="Array">
@@ -47442,6 +52826,8 @@
</description>
</method>
<method name="tile_set_texture">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="texture" type="Texture">
@@ -47451,6 +52837,8 @@
</description>
</method>
<method name="tile_set_texture_offset">
+ <return type="void">
+ </return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="texture_offset" type="Vector2">
@@ -47479,7 +52867,7 @@
</description>
</method>
<method name="get_timer_process_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Timer.TimerProcessMode">
</return>
<description>
Return the timer's processing mode.
@@ -47520,6 +52908,8 @@
</description>
</method>
<method name="set_autostart">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -47527,6 +52917,8 @@
</description>
</method>
<method name="set_one_shot">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -47534,6 +52926,8 @@
</description>
</method>
<method name="set_paused">
+ <return type="void">
+ </return>
<argument index="0" name="paused" type="bool">
</argument>
<description>
@@ -47541,13 +52935,17 @@
</description>
</method>
<method name="set_timer_process_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Timer.TimerProcessMode">
</argument>
<description>
Set the timer's processing mode (fixed or idle, use TIMER_PROCESS_* constants as argument).
</description>
</method>
<method name="set_wait_time">
+ <return type="void">
+ </return>
<argument index="0" name="time_sec" type="float">
</argument>
<description>
@@ -47555,11 +52953,15 @@
</description>
</method>
<method name="start">
+ <return type="void">
+ </return>
<description>
Start the timer.
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
Stop (cancel) the timer.
</description>
@@ -47570,7 +52972,7 @@
</member>
<member name="one_shot" type="bool" setter="set_one_shot" getter="is_one_shot" brief="">
</member>
- <member name="process_mode" type="int" setter="set_timer_process_mode" getter="get_timer_process_mode" brief="">
+ <member name="process_mode" type="int" setter="set_timer_process_mode" getter="get_timer_process_mode" brief="" enum="Timer.TimerProcessMode">
</member>
<member name="wait_time" type="float" setter="set_wait_time" getter="get_wait_time" brief="">
</member>
@@ -47638,31 +53040,31 @@
</description>
</method>
<method name="get_bitmask" qualifiers="const">
- <return type="Object">
+ <return type="BitMap">
</return>
<description>
</description>
</method>
<method name="get_shape" qualifiers="const">
- <return type="Object">
+ <return type="Shape2D">
</return>
<description>
</description>
</method>
<method name="get_texture" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
</method>
<method name="get_texture_pressed" qualifiers="const">
- <return type="Object">
+ <return type="Texture">
</return>
<description>
</description>
</method>
<method name="get_visibility_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TouchScreenButton.VisibilityMode">
</return>
<description>
</description>
@@ -47692,55 +53094,73 @@
</description>
</method>
<method name="set_action">
+ <return type="void">
+ </return>
<argument index="0" name="action" type="String">
</argument>
<description>
</description>
</method>
<method name="set_bitmask">
- <argument index="0" name="bitmask" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="bitmask" type="BitMap">
</argument>
<description>
</description>
</method>
<method name="set_passby_press">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_shape">
- <argument index="0" name="shape" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="shape" type="Shape2D">
</argument>
<description>
</description>
</method>
<method name="set_shape_centered">
+ <return type="void">
+ </return>
<argument index="0" name="bool" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_shape_visible">
+ <return type="void">
+ </return>
<argument index="0" name="bool" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_texture">
- <argument index="0" name="texture" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_texture_pressed">
- <argument index="0" name="texture_pressed" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture_pressed" type="Texture">
</argument>
<description>
</description>
</method>
<method name="set_visibility_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="TouchScreenButton.VisibilityMode">
</argument>
<description>
</description>
@@ -47763,7 +53183,7 @@
</member>
<member name="shape_visible" type="bool" setter="set_shape_visible" getter="is_shape_visible" brief="">
</member>
- <member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" brief="">
+ <member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" brief="" enum="TouchScreenButton.VisibilityMode">
</member>
</members>
<signals>
@@ -47847,6 +53267,16 @@
Returns the inverse of the transfrom, under the assumption that the transformation is composed of rotation, scaling and translation.
</description>
</method>
+ <method name="interpolate_with">
+ <return type="Transform">
+ </return>
+ <argument index="0" name="transform" type="Transform">
+ </argument>
+ <argument index="1" name="weight" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="inverse">
<return type="Transform">
</return>
@@ -48014,9 +53444,9 @@
<method name="interpolate_with">
<return type="Transform2D">
</return>
- <argument index="0" name="m" type="Transform2D">
+ <argument index="0" name="transform" type="Transform2D">
</argument>
- <argument index="1" name="c" type="float">
+ <argument index="1" name="weight" type="float">
</argument>
<description>
</description>
@@ -48094,6 +53524,8 @@
</description>
<methods>
<method name="add_message">
+ <return type="void">
+ </return>
<argument index="0" name="src_message" type="String">
</argument>
<argument index="1" name="xlated_message" type="String">
@@ -48103,6 +53535,8 @@
</description>
</method>
<method name="erase_message">
+ <return type="void">
+ </return>
<argument index="0" name="src_message" type="String">
</argument>
<description>
@@ -48139,6 +53573,8 @@
</description>
</method>
<method name="set_locale">
+ <return type="void">
+ </return>
<argument index="0" name="locale" type="String">
</argument>
<description>
@@ -48163,12 +53599,16 @@
</description>
<methods>
<method name="add_translation">
+ <return type="void">
+ </return>
<argument index="0" name="translation" type="Translation">
</argument>
<description>
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
</description>
</method>
@@ -48179,12 +53619,16 @@
</description>
</method>
<method name="remove_translation">
+ <return type="void">
+ </return>
<argument index="0" name="translation" type="Translation">
</argument>
<description>
</description>
</method>
<method name="set_locale">
+ <return type="void">
+ </return>
<argument index="0" name="locale" type="String">
</argument>
<description>
@@ -48229,24 +53673,34 @@
</description>
</method>
<method name="clear">
+ <return type="void">
+ </return>
<description>
Clear the tree. This erases all of the items.
</description>
</method>
<method name="create_item">
- <return type="TreeItem">
+ <return type="Object">
</return>
- <argument index="0" name="parent" type="TreeItem" default="NULL">
+ <argument index="0" name="parent" type="Object" default="null">
</argument>
<description>
Create an item in the tree and add it as the last child of [code]parent[/code]. If parent is not given, it will be added as the last child of the root, or it'll the be the root itself if the tree is empty.
</description>
</method>
<method name="ensure_cursor_is_visible">
+ <return type="void">
+ </return>
<description>
Make the current selected item visible. This will scroll the tree to make sure the selected item is in sight.
</description>
</method>
+ <method name="get_allow_reselect" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_allow_rmb_select" qualifiers="const">
<return type="bool">
</return>
@@ -48319,7 +53773,7 @@
<method name="get_item_area_rect" qualifiers="const">
<return type="Rect2">
</return>
- <argument index="0" name="item" type="TreeItem">
+ <argument index="0" name="item" type="Object">
</argument>
<argument index="1" name="column" type="int" default="-1">
</argument>
@@ -48339,7 +53793,7 @@
<method name="get_next_selected">
<return type="TreeItem">
</return>
- <argument index="0" name="from" type="TreeItem">
+ <argument index="0" name="from" type="Object">
</argument>
<description>
Get the next selected item after the given one.
@@ -48380,21 +53834,24 @@
Get the column number of the current selection.
</description>
</method>
- <method name="get_single_select_cell_editing_only_when_already_selected" qualifiers="const">
+ <method name="is_folding_hidden" qualifiers="const">
<return type="bool">
</return>
<description>
- Get whether the editing of a cell should only happen when it is already selected.
+ Get whether the folding arrow is hidden.
</description>
</method>
- <method name="is_folding_hidden" qualifiers="const">
- <return type="bool">
+ <method name="set_allow_reselect">
+ <return type="void">
</return>
+ <argument index="0" name="allow" type="bool">
+ </argument>
<description>
- Get whether the folding arrow is hidden.
</description>
</method>
<method name="set_allow_rmb_select">
+ <return type="void">
+ </return>
<argument index="0" name="allow" type="bool">
</argument>
<description>
@@ -48402,6 +53859,8 @@
</description>
</method>
<method name="set_column_expand">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="expand" type="bool">
@@ -48411,6 +53870,8 @@
</description>
</method>
<method name="set_column_min_width">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="min_width" type="int">
@@ -48420,6 +53881,8 @@
</description>
</method>
<method name="set_column_title">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="title" type="String">
@@ -48429,6 +53892,8 @@
</description>
</method>
<method name="set_column_titles_visible">
+ <return type="void">
+ </return>
<argument index="0" name="visible" type="bool">
</argument>
<description>
@@ -48436,6 +53901,8 @@
</description>
</method>
<method name="set_columns">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
@@ -48443,6 +53910,8 @@
</description>
</method>
<method name="set_drop_mode_flags">
+ <return type="void">
+ </return>
<argument index="0" name="flags" type="int">
</argument>
<description>
@@ -48450,6 +53919,8 @@
</description>
</method>
<method name="set_hide_folding">
+ <return type="void">
+ </return>
<argument index="0" name="hide" type="bool">
</argument>
<description>
@@ -48457,6 +53928,8 @@
</description>
</method>
<method name="set_hide_root">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -48464,19 +53937,14 @@
</description>
</method>
<method name="set_select_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Tree.SelectMode">
</argument>
<description>
Set the selection mode. Use one of the [code]SELECT_*[/code] constants.
</description>
</method>
- <method name="set_single_select_cell_editing_only_when_already_selected">
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- Set whether the editing of a cell should only happen when it is already selected.
- </description>
- </method>
</methods>
<signals>
<signal name="button_pressed">
@@ -48540,6 +54008,10 @@
Emitted when an item is editted.
</description>
</signal>
+ <signal name="item_rmb_edited">
+ <description>
+ </description>
+ </signal>
<signal name="item_rmb_selected">
<argument index="0" name="pos" type="Vector2">
</argument>
@@ -48663,6 +54135,8 @@
</description>
<methods>
<method name="add_button">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="button" type="Texture">
@@ -48677,24 +54151,32 @@
</description>
</method>
<method name="clear_custom_bg_color">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<description>
</description>
</method>
<method name="clear_custom_color">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<description>
</description>
</method>
<method name="deselect">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<description>
</description>
</method>
<method name="erase_button">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="button_idx" type="int">
@@ -48721,7 +54203,7 @@
</description>
</method>
<method name="get_cell_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TreeItem.TreeCellMode">
</return>
<argument index="0" name="column" type="int">
</argument>
@@ -48775,6 +54257,8 @@
</description>
</method>
<method name="get_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<description>
@@ -48835,7 +54319,7 @@
</description>
</method>
<method name="get_text_align" qualifiers="const">
- <return type="int">
+ <return type="int" enum="TreeItem.TextAlign">
</return>
<argument index="0" name="column" type="int">
</argument>
@@ -48913,15 +54397,19 @@
</description>
</method>
<method name="move_to_bottom">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="move_to_top">
+ <return type="void">
+ </return>
<description>
</description>
</method>
<method name="remove_child">
- <return type="TreeItem">
+ <return type="void">
</return>
<argument index="0" name="child" type="Object">
</argument>
@@ -48929,12 +54417,16 @@
</description>
</method>
<method name="select">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<description>
</description>
</method>
<method name="set_button">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="button_idx" type="int">
@@ -48945,14 +54437,18 @@
</description>
</method>
<method name="set_cell_mode">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
- <argument index="1" name="mode" type="int">
+ <argument index="1" name="mode" type="int" enum="TreeItem.TreeCellMode">
</argument>
<description>
</description>
</method>
<method name="set_checked">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="checked" type="bool">
@@ -48961,12 +54457,16 @@
</description>
</method>
<method name="set_collapsed">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_custom_as_button">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -48975,6 +54475,8 @@
</description>
</method>
<method name="set_custom_bg_color">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="color" type="Color">
@@ -48985,6 +54487,8 @@
</description>
</method>
<method name="set_custom_color">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="color" type="Color">
@@ -48993,6 +54497,8 @@
</description>
</method>
<method name="set_custom_draw">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="object" type="Object">
@@ -49003,12 +54509,16 @@
</description>
</method>
<method name="set_disable_folding">
+ <return type="void">
+ </return>
<argument index="0" name="disable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_editable">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="enabled" type="bool">
@@ -49017,6 +54527,8 @@
</description>
</method>
<method name="set_expand_right">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="enable" type="bool">
@@ -49025,6 +54537,8 @@
</description>
</method>
<method name="set_icon">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="texture" type="Texture">
@@ -49033,6 +54547,8 @@
</description>
</method>
<method name="set_icon_max_width">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="width" type="int">
@@ -49041,6 +54557,8 @@
</description>
</method>
<method name="set_icon_region">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="region" type="Rect2">
@@ -49049,6 +54567,8 @@
</description>
</method>
<method name="set_metadata">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="meta" type="Variant">
@@ -49057,6 +54577,8 @@
</description>
</method>
<method name="set_range">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="value" type="float">
@@ -49065,6 +54587,8 @@
</description>
</method>
<method name="set_range_config">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="min" type="float">
@@ -49079,6 +54603,8 @@
</description>
</method>
<method name="set_selectable">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="selectable" type="bool">
@@ -49087,6 +54613,8 @@
</description>
</method>
<method name="set_text">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="text" type="String">
@@ -49095,14 +54623,18 @@
</description>
</method>
<method name="set_text_align">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
- <argument index="1" name="text_align" type="int">
+ <argument index="1" name="text_align" type="int" enum="TreeItem.TextAlign">
</argument>
<description>
</description>
</method>
<method name="set_tooltip">
+ <return type="void">
+ </return>
<argument index="0" name="column" type="int">
</argument>
<argument index="1" name="tooltip" type="String">
@@ -49167,9 +54699,9 @@
</argument>
<argument index="5" name="duration" type="float">
</argument>
- <argument index="6" name="trans_type" type="int">
+ <argument index="6" name="trans_type" type="int" enum="Tween.TransitionType">
</argument>
- <argument index="7" name="ease_type" type="int">
+ <argument index="7" name="ease_type" type="int" enum="Tween.EaseType">
</argument>
<argument index="8" name="delay" type="float" default="0">
</argument>
@@ -49193,9 +54725,9 @@
</argument>
<argument index="5" name="duration" type="float">
</argument>
- <argument index="6" name="trans_type" type="int">
+ <argument index="6" name="trans_type" type="int" enum="Tween.TransitionType">
</argument>
- <argument index="7" name="ease_type" type="int">
+ <argument index="7" name="ease_type" type="int" enum="Tween.EaseType">
</argument>
<argument index="8" name="delay" type="float" default="0">
</argument>
@@ -49219,7 +54751,7 @@
</description>
</method>
<method name="get_tween_process_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Tween.TweenProcessMode">
</return>
<description>
Returns the process mode that has been set from editor GUI or [method set_tween_process_mode]
@@ -49234,15 +54766,15 @@
</argument>
<argument index="2" name="callback" type="String">
</argument>
- <argument index="3" name="arg1" type="Variant" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="null">
</argument>
- <argument index="4" name="arg2" type="Variant" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="null">
</argument>
- <argument index="5" name="arg3" type="Variant" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="null">
</argument>
- <argument index="6" name="arg4" type="Variant" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="null">
</argument>
- <argument index="7" name="arg5" type="Variant" default="NULL">
+ <argument index="7" name="arg5" type="Variant" default="null">
</argument>
<description>
Call [code]callback[/code] of [code]object[/code] after [code]duration[/code]. [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
@@ -49257,15 +54789,15 @@
</argument>
<argument index="2" name="callback" type="String">
</argument>
- <argument index="3" name="arg1" type="Variant" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="null">
</argument>
- <argument index="4" name="arg2" type="Variant" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="null">
</argument>
- <argument index="5" name="arg3" type="Variant" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="null">
</argument>
- <argument index="6" name="arg4" type="Variant" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="null">
</argument>
- <argument index="7" name="arg5" type="Variant" default="NULL">
+ <argument index="7" name="arg5" type="Variant" default="null">
</argument>
<description>
Call [code]callback[/code] of [code]object[/code] after [code]duration[/code] on the main thread (similar to [methog Object.call_deferred). [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
@@ -49284,9 +54816,9 @@
</argument>
<argument index="4" name="duration" type="float">
</argument>
- <argument index="5" name="trans_type" type="int">
+ <argument index="5" name="trans_type" type="int" enum="Tween.TransitionType">
</argument>
- <argument index="6" name="ease_type" type="int">
+ <argument index="6" name="ease_type" type="int" enum="Tween.EaseType">
</argument>
<argument index="7" name="delay" type="float" default="0">
</argument>
@@ -49308,9 +54840,9 @@
</argument>
<argument index="4" name="duration" type="float">
</argument>
- <argument index="5" name="trans_type" type="int">
+ <argument index="5" name="trans_type" type="int" enum="Tween.TransitionType">
</argument>
- <argument index="6" name="ease_type" type="int">
+ <argument index="6" name="ease_type" type="int" enum="Tween.EaseType">
</argument>
<argument index="7" name="delay" type="float" default="0">
</argument>
@@ -49397,6 +54929,8 @@
</description>
</method>
<method name="set_active">
+ <return type="void">
+ </return>
<argument index="0" name="active" type="bool">
</argument>
<description>
@@ -49404,6 +54938,8 @@
</description>
</method>
<method name="set_repeat">
+ <return type="void">
+ </return>
<argument index="0" name="repeat" type="bool">
</argument>
<description>
@@ -49411,6 +54947,8 @@
</description>
</method>
<method name="set_speed_scale">
+ <return type="void">
+ </return>
<argument index="0" name="speed" type="float">
</argument>
<description>
@@ -49418,7 +54956,9 @@
</description>
</method>
<method name="set_tween_process_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Tween.TweenProcessMode">
</argument>
<description>
Set whether the Tween uses [code]_process[/code] or [code]_fixed_process[/code] (accepts TWEEN_PROCESS_IDLE and TWEEN_PROCESS_FIXED constants, respectively).
@@ -49464,9 +55004,9 @@
</argument>
<argument index="5" name="duration" type="float">
</argument>
- <argument index="6" name="trans_type" type="int">
+ <argument index="6" name="trans_type" type="int" enum="Tween.TransitionType">
</argument>
- <argument index="7" name="ease_type" type="int">
+ <argument index="7" name="ease_type" type="int" enum="Tween.EaseType">
</argument>
<argument index="8" name="delay" type="float" default="0">
</argument>
@@ -49490,9 +55030,9 @@
</argument>
<argument index="5" name="duration" type="float">
</argument>
- <argument index="6" name="trans_type" type="int">
+ <argument index="6" name="trans_type" type="int" enum="Tween.TransitionType">
</argument>
- <argument index="7" name="ease_type" type="int">
+ <argument index="7" name="ease_type" type="int" enum="Tween.EaseType">
</argument>
<argument index="8" name="delay" type="float" default="0">
</argument>
@@ -49510,7 +55050,7 @@
</method>
</methods>
<members>
- <member name="playback_process_mode" type="int" setter="set_tween_process_mode" getter="get_tween_process_mode" brief="">
+ <member name="playback_process_mode" type="int" setter="set_tween_process_mode" getter="get_tween_process_mode" brief="" enum="Tween.TweenProcessMode">
</member>
</members>
<signals>
@@ -49569,7 +55109,7 @@
Means that the animation is interpolated with a quadratic (to the power of 2) function.
</constant>
<constant name="TRANS_EXPO" value="5">
- Means that the animation is interpolated with a exponential (some number to the power of x) function.
+ Means that the animation is interpolated with an exponential (some number to the power of x) function.
</constant>
<constant name="TRANS_ELASTIC" value="6">
Means that the animation is interpolated with elasticity, wiggling around the edges.
@@ -49610,6 +55150,8 @@
</description>
<methods>
<method name="add_do_method" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="object" type="Object">
</argument>
<argument index="1" name="method" type="String">
@@ -49618,6 +55160,8 @@
</description>
</method>
<method name="add_do_property">
+ <return type="void">
+ </return>
<argument index="0" name="object" type="Object">
</argument>
<argument index="1" name="property" type="String">
@@ -49629,6 +55173,8 @@
</description>
</method>
<method name="add_do_reference">
+ <return type="void">
+ </return>
<argument index="0" name="object" type="Object">
</argument>
<description>
@@ -49636,6 +55182,8 @@
</description>
</method>
<method name="add_undo_method" qualifiers="vararg">
+ <return type="Variant">
+ </return>
<argument index="0" name="object" type="Object">
</argument>
<argument index="1" name="method" type="String">
@@ -49644,6 +55192,8 @@
</description>
</method>
<method name="add_undo_property">
+ <return type="void">
+ </return>
<argument index="0" name="object" type="Object">
</argument>
<argument index="1" name="property" type="String">
@@ -49655,6 +55205,8 @@
</description>
</method>
<method name="add_undo_reference">
+ <return type="void">
+ </return>
<argument index="0" name="object" type="Object">
</argument>
<description>
@@ -49662,19 +55214,25 @@
</description>
</method>
<method name="clear_history">
+ <return type="void">
+ </return>
<description>
Clear the undo/redo history and associated references.
</description>
</method>
<method name="commit_action">
+ <return type="void">
+ </return>
<description>
Commit the action. All 'do' methods/properties are called/set when this function is called.
</description>
</method>
<method name="create_action">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="merge_mode" type="int" default="0">
+ <argument index="1" name="merge_mode" type="int" enum="UndoRedo.MergeMode" default="0">
</argument>
<description>
Create a new action. After this is called, do all your calls to [method add_do_method], [method add_undo_method], [method add_do_property] and [method add_undo_property].
@@ -49740,6 +55298,8 @@
</theme_item>
<theme_item name="grabber_highlight" type="StyleBox">
</theme_item>
+ <theme_item name="grabber_pressed" type="StyleBox">
+ </theme_item>
<theme_item name="increment" type="Texture">
</theme_item>
<theme_item name="increment_highlight" type="Texture">
@@ -49780,6 +55340,8 @@
<constants>
</constants>
<theme_items>
+ <theme_item name="focus" type="StyleBox">
+ </theme_item>
<theme_item name="grabber" type="Texture">
</theme_item>
<theme_item name="grabber_disabled" type="Texture">
@@ -50285,13 +55847,13 @@
</member>
</members>
<constants>
- <constant name="AXIS_X" value="0">
+ <constant name="AXIS_X" value="0" enum="">
Enumerated value for the X axis. Returned by functions like max_axis or min_axis.
</constant>
- <constant name="AXIS_Y" value="1">
+ <constant name="AXIS_Y" value="1" enum="">
Enumerated value for the Y axis.
</constant>
- <constant name="AXIS_Z" value="2">
+ <constant name="AXIS_Z" value="2" enum="">
Enumerated value for the Z axis.
</constant>
</constants>
@@ -50345,30 +55907,40 @@
</description>
</method>
<method name="set_brake">
+ <return type="void">
+ </return>
<argument index="0" name="brake" type="float">
</argument>
<description>
</description>
</method>
<method name="set_engine_force">
+ <return type="void">
+ </return>
<argument index="0" name="engine_force" type="float">
</argument>
<description>
</description>
</method>
<method name="set_friction">
+ <return type="void">
+ </return>
<argument index="0" name="friction" type="float">
</argument>
<description>
</description>
</method>
<method name="set_mass">
+ <return type="void">
+ </return>
<argument index="0" name="mass" type="float">
</argument>
<description>
</description>
</method>
<method name="set_steering">
+ <return type="void">
+ </return>
<argument index="0" name="steering" type="float">
</argument>
<description>
@@ -50470,66 +56042,88 @@
</description>
</method>
<method name="set_damping_compression">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_damping_relaxation">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_friction_slip">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_radius">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_roll_influence">
+ <return type="void">
+ </return>
<argument index="0" name="roll_influence" type="float">
</argument>
<description>
</description>
</method>
<method name="set_suspension_max_force">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_suspension_rest_length">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_suspension_stiffness">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_suspension_travel">
+ <return type="void">
+ </return>
<argument index="0" name="length" type="float">
</argument>
<description>
</description>
</method>
<method name="set_use_as_steering">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_use_as_traction">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -50656,11 +56250,15 @@
</description>
</method>
<method name="play">
+ <return type="void">
+ </return>
<description>
Start the video playback.
</description>
</method>
<method name="set_audio_track">
+ <return type="void">
+ </return>
<argument index="0" name="track" type="int">
</argument>
<description>
@@ -50668,6 +56266,8 @@
</description>
</method>
<method name="set_autoplay">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -50675,6 +56275,8 @@
</description>
</method>
<method name="set_buffering_msec">
+ <return type="void">
+ </return>
<argument index="0" name="msec" type="int">
</argument>
<description>
@@ -50682,6 +56284,8 @@
</description>
</method>
<method name="set_expand">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -50689,6 +56293,8 @@
</description>
</method>
<method name="set_paused">
+ <return type="void">
+ </return>
<argument index="0" name="paused" type="bool">
</argument>
<description>
@@ -50696,6 +56302,8 @@
</description>
</method>
<method name="set_stream">
+ <return type="void">
+ </return>
<argument index="0" name="stream" type="VideoStream">
</argument>
<description>
@@ -50703,6 +56311,8 @@
</description>
</method>
<method name="set_volume">
+ <return type="void">
+ </return>
<argument index="0" name="volume" type="float">
</argument>
<description>
@@ -50710,6 +56320,8 @@
</description>
</method>
<method name="set_volume_db">
+ <return type="void">
+ </return>
<argument index="0" name="db" type="float">
</argument>
<description>
@@ -50717,6 +56329,8 @@
</description>
</method>
<method name="stop">
+ <return type="void">
+ </return>
<description>
Stop the video playback.
</description>
@@ -50762,11 +56376,6 @@
Finally, viewports can also behave as render targets, in which case they will not be visible unless the associated texture is used to draw.
</description>
<methods>
- <method name="clear">
- <description>
- Clear the viewport manually.
- </description>
- </method>
<method name="find_world" qualifiers="const">
<return type="World">
</return>
@@ -50795,15 +56404,14 @@
Get the canvas transform of the viewport.
</description>
</method>
- <method name="get_clear_on_new_frame" qualifiers="const">
- <return type="bool">
+ <method name="get_clear_mode" qualifiers="const">
+ <return type="int" enum="Viewport.ClearMode">
</return>
<description>
- Return whether automatic clearing of the render target on each frame is enabled.
</description>
</method>
<method name="get_debug_draw" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Viewport.DebugDraw">
</return>
<description>
</description>
@@ -50837,7 +56445,7 @@
</description>
</method>
<method name="get_msaa" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Viewport.MSAA">
</return>
<description>
</description>
@@ -50852,13 +56460,13 @@
<method name="get_render_info">
<return type="int">
</return>
- <argument index="0" name="info" type="int">
+ <argument index="0" name="info" type="int" enum="Viewport.RenderInfo">
</argument>
<description>
</description>
</method>
<method name="get_shadow_atlas_quadrant_subdiv" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Viewport.ShadowAtlasQuadrantSubdiv">
</return>
<argument index="0" name="quadrant" type="int">
</argument>
@@ -50893,14 +56501,14 @@
</description>
</method>
<method name="get_update_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Viewport.UpdateMode">
</return>
<description>
Get when the viewport would be updated, will be one of the [code]UPDATE_*[/code] constants.
</description>
</method>
<method name="get_usage" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Viewport.Usage">
</return>
<description>
</description>
@@ -50962,7 +56570,9 @@
</description>
</method>
<method name="input">
- <argument index="0" name="local_event" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="local_event" type="InputEvent">
</argument>
<description>
</description>
@@ -51016,6 +56626,8 @@
</description>
</method>
<method name="set_as_audio_listener">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -51023,6 +56635,8 @@
</description>
</method>
<method name="set_as_audio_listener_2d">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -51030,37 +56644,49 @@
</description>
</method>
<method name="set_attach_to_screen_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<description>
</description>
</method>
<method name="set_canvas_transform">
+ <return type="void">
+ </return>
<argument index="0" name="xform" type="Transform2D">
</argument>
<description>
Set the canvas transform of the viewport, useful for changing the on-screen positions of all child [CanvasItem]\ s. This is relative to the global canvas transform of the viewport.
</description>
</method>
- <method name="set_clear_on_new_frame">
- <argument index="0" name="enable" type="bool">
+ <method name="set_clear_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Viewport.ClearMode">
</argument>
<description>
</description>
</method>
<method name="set_debug_draw">
- <argument index="0" name="debug_draw" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="debug_draw" type="int" enum="Viewport.DebugDraw">
</argument>
<description>
</description>
</method>
<method name="set_disable_3d">
+ <return type="void">
+ </return>
<argument index="0" name="disable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_disable_input">
+ <return type="void">
+ </return>
<argument index="0" name="disable" type="bool">
</argument>
<description>
@@ -51068,6 +56694,8 @@
</description>
</method>
<method name="set_global_canvas_transform">
+ <return type="void">
+ </return>
<argument index="0" name="xform" type="Transform2D">
</argument>
<description>
@@ -51075,18 +56703,24 @@
</description>
</method>
<method name="set_hdr">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_msaa">
- <argument index="0" name="msaa" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="msaa" type="int" enum="Viewport.MSAA">
</argument>
<description>
</description>
</method>
<method name="set_physics_object_picking">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -51094,20 +56728,26 @@
</description>
</method>
<method name="set_shadow_atlas_quadrant_subdiv">
+ <return type="void">
+ </return>
<argument index="0" name="quadrant" type="int">
</argument>
- <argument index="1" name="subdiv" type="int">
+ <argument index="1" name="subdiv" type="int" enum="Viewport.ShadowAtlasQuadrantSubdiv">
</argument>
<description>
</description>
</method>
<method name="set_shadow_atlas_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="int">
</argument>
<description>
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
@@ -51115,17 +56755,21 @@
</description>
</method>
<method name="set_size_override">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
- <argument index="1" name="size" type="Vector2" default="Vector2(-1, -1)">
+ <argument index="1" name="size" type="Vector2" default="Vector2( -1, -1 )">
</argument>
- <argument index="2" name="margin" type="Vector2" default="Vector2(0, 0)">
+ <argument index="2" name="margin" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
Set the size override of the viewport. If the enable parameter is true, it would use the override, otherwise it would use the default size. If the size parameter is equal to [code](-1, -1)[/code], it won't update the size.
</description>
</method>
<method name="set_size_override_stretch">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
@@ -51133,6 +56777,8 @@
</description>
</method>
<method name="set_transparent_background">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -51140,19 +56786,33 @@
</description>
</method>
<method name="set_update_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Viewport.UpdateMode">
</argument>
<description>
Set when the render target would be updated, using the [code]UPDATE_*[/code] constants
</description>
</method>
<method name="set_usage">
- <argument index="0" name="usage" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="usage" type="int" enum="Viewport.Usage">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_use_arvr">
+ <return type="void">
+ </return>
+ <argument index="0" name="use" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_use_own_world">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -51160,6 +56820,8 @@
</description>
</method>
<method name="set_vflip">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -51167,6 +56829,8 @@
</description>
</method>
<method name="set_world">
+ <return type="void">
+ </return>
<argument index="0" name="world" type="World">
</argument>
<description>
@@ -51174,23 +56838,37 @@
</description>
</method>
<method name="set_world_2d">
+ <return type="void">
+ </return>
<argument index="0" name="world_2d" type="World2D">
</argument>
<description>
</description>
</method>
<method name="unhandled_input">
- <argument index="0" name="local_event" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="local_event" type="InputEvent">
</argument>
<description>
</description>
</method>
<method name="update_worlds">
+ <return type="void">
+ </return>
<description>
Force update of the 2D and 3D worlds.
</description>
</method>
+ <method name="use_arvr">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="warp_mouse">
+ <return type="void">
+ </return>
<argument index="0" name="to_pos" type="Vector2">
</argument>
<description>
@@ -51199,11 +56877,13 @@
</method>
</methods>
<members>
+ <member name="arvr" type="bool" setter="set_use_arvr" getter="use_arvr" brief="">
+ </member>
<member name="audio_listener_enable_2d" type="bool" setter="set_as_audio_listener_2d" getter="is_audio_listener_2d" brief="">
</member>
<member name="audio_listener_enable_3d" type="bool" setter="set_as_audio_listener" getter="is_audio_listener" brief="">
</member>
- <member name="debug_draw" type="int" setter="set_debug_draw" getter="get_debug_draw" brief="">
+ <member name="debug_draw" type="int" setter="set_debug_draw" getter="get_debug_draw" brief="" enum="Viewport.DebugDraw">
</member>
<member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled" brief="">
</member>
@@ -51211,33 +56891,33 @@
</member>
<member name="hdr" type="bool" setter="set_hdr" getter="get_hdr" brief="">
</member>
- <member name="msaa" type="int" setter="set_msaa" getter="get_msaa" brief="">
+ <member name="msaa" type="int" setter="set_msaa" getter="get_msaa" brief="" enum="Viewport.MSAA">
</member>
<member name="own_world" type="bool" setter="set_use_own_world" getter="is_using_own_world" brief="">
</member>
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" brief="">
</member>
- <member name="render_target_clear_on_new_frame" type="bool" setter="set_clear_on_new_frame" getter="get_clear_on_new_frame" brief="">
+ <member name="render_target_clear_mode" type="int" setter="set_clear_mode" getter="get_clear_mode" brief="" enum="Viewport.ClearMode">
</member>
- <member name="render_target_update_mode" type="int" setter="set_update_mode" getter="get_update_mode" brief="">
+ <member name="render_target_update_mode" type="int" setter="set_update_mode" getter="get_update_mode" brief="" enum="Viewport.UpdateMode">
</member>
<member name="render_target_v_flip" type="bool" setter="set_vflip" getter="get_vflip" brief="">
</member>
- <member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="">
+ <member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="" enum="Viewport.ShadowAtlasQuadrantSubdiv">
</member>
- <member name="shadow_atlas_quad_1" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="">
+ <member name="shadow_atlas_quad_1" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="" enum="Viewport.ShadowAtlasQuadrantSubdiv">
</member>
- <member name="shadow_atlas_quad_2" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="">
+ <member name="shadow_atlas_quad_2" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="" enum="Viewport.ShadowAtlasQuadrantSubdiv">
</member>
- <member name="shadow_atlas_quad_3" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="">
+ <member name="shadow_atlas_quad_3" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" brief="" enum="Viewport.ShadowAtlasQuadrantSubdiv">
</member>
<member name="shadow_atlas_size" type="int" setter="set_shadow_atlas_size" getter="get_shadow_atlas_size" brief="">
</member>
- <member name="size" type="Rect2" setter="set_size" getter="get_size" brief="">
+ <member name="size" type="Vector2" setter="set_size" getter="get_size" brief="">
</member>
<member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" brief="">
</member>
- <member name="usage" type="int" setter="set_usage" getter="get_usage" brief="">
+ <member name="usage" type="int" setter="set_usage" getter="get_usage" brief="" enum="Viewport.Usage">
</member>
<member name="world" type="World" setter="set_world" getter="get_world" brief="">
</member>
@@ -51324,6 +57004,8 @@
</description>
</method>
<method name="set_stretch">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -51350,6 +57032,8 @@
</description>
</method>
<method name="set_viewport_path_in_scene">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="NodePath">
</argument>
<description>
@@ -51374,14 +57058,16 @@
<method name="is_enabler_enabled" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="enabler" type="int">
+ <argument index="0" name="enabler" type="int" enum="VisibilityEnabler.Enabler">
</argument>
<description>
Returns whether the specified enabler was set to true or not.
</description>
</method>
<method name="set_enabler">
- <argument index="0" name="enabler" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="enabler" type="int" enum="VisibilityEnabler.Enabler">
</argument>
<argument index="1" name="enabled" type="bool">
</argument>
@@ -51418,14 +57104,16 @@
<method name="is_enabler_enabled" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="enabler" type="int">
+ <argument index="0" name="enabler" type="int" enum="VisibilityEnabler2D.Enabler">
</argument>
<description>
Returns whether the specified enabler was set to true or not.
</description>
</method>
<method name="set_enabler">
- <argument index="0" name="enabler" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="enabler" type="int" enum="VisibilityEnabler2D.Enabler">
</argument>
<argument index="1" name="enabled" type="bool">
</argument>
@@ -51493,6 +57181,8 @@
</description>
</method>
<method name="set_aabb">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect3">
</argument>
<description>
@@ -51556,6 +57246,8 @@
</description>
</method>
<method name="set_rect">
+ <return type="void">
+ </return>
<argument index="0" name="rect" type="Rect2">
</argument>
<description>
@@ -51621,12 +57313,16 @@
</description>
</method>
<method name="set_base">
+ <return type="void">
+ </return>
<argument index="0" name="base" type="RID">
</argument>
<description>
</description>
</method>
<method name="set_layer_mask">
+ <return type="void">
+ </return>
<argument index="0" name="mask" type="int">
</argument>
<description>
@@ -51647,33 +57343,41 @@
</description>
<methods>
<method name="add_custom_signal">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="add_function">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="add_node">
+ <return type="void">
+ </return>
<argument index="0" name="func" type="String">
</argument>
<argument index="1" name="id" type="int">
</argument>
- <argument index="2" name="node" type="Object">
+ <argument index="2" name="node" type="VisualScriptNode">
</argument>
- <argument index="3" name="pos" type="Vector2" default="Vector2(0, 0)">
+ <argument index="3" name="pos" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
</description>
</method>
<method name="add_variable">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="default_value" type="Variant" default="NULL">
+ <argument index="1" name="default_value" type="Variant" default="null">
</argument>
<argument index="2" name="export" type="bool" default="false">
</argument>
@@ -51681,9 +57385,11 @@
</description>
</method>
<method name="custom_signal_add_argument">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="type" type="int">
+ <argument index="1" name="type" type="int" enum="Variant.Type">
</argument>
<argument index="2" name="argname" type="String">
</argument>
@@ -51711,7 +57417,7 @@
</description>
</method>
<method name="custom_signal_get_argument_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<argument index="0" name="name" type="String">
</argument>
@@ -51721,14 +57427,18 @@
</description>
</method>
<method name="custom_signal_remove_argument">
- <argument index="0" name="argidx" type="String">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="arg1" type="int">
+ <argument index="1" name="argidx" type="int">
</argument>
<description>
</description>
</method>
<method name="custom_signal_set_argument_name">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="argidx" type="int">
@@ -51739,16 +57449,20 @@
</description>
</method>
<method name="custom_signal_set_argument_type">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="argidx" type="int">
</argument>
- <argument index="2" name="type" type="int">
+ <argument index="2" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
<method name="custom_signal_swap_argument">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="argidx" type="int">
@@ -51759,6 +57473,8 @@
</description>
</method>
<method name="data_connect">
+ <return type="void">
+ </return>
<argument index="0" name="func" type="String">
</argument>
<argument index="1" name="from_node" type="int">
@@ -51773,6 +57489,8 @@
</description>
</method>
<method name="data_disconnect">
+ <return type="void">
+ </return>
<argument index="0" name="func" type="String">
</argument>
<argument index="1" name="from_node" type="int">
@@ -51797,13 +57515,13 @@
<method name="get_function_scroll" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="arg0" type="String">
+ <argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="get_node" qualifiers="const">
- <return type="Object">
+ <return type="VisualScriptNode">
</return>
<argument index="0" name="func" type="String">
</argument>
@@ -51823,6 +57541,8 @@
</description>
</method>
<method name="get_variable_default_value" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -51909,18 +57629,24 @@
</description>
</method>
<method name="remove_custom_signal">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="remove_function">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="remove_node">
+ <return type="void">
+ </return>
<argument index="0" name="func" type="String">
</argument>
<argument index="1" name="id" type="int">
@@ -51929,12 +57655,16 @@
</description>
</method>
<method name="remove_variable">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="rename_custom_signal">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="new_name" type="String">
@@ -51943,6 +57673,8 @@
</description>
</method>
<method name="rename_function">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="new_name" type="String">
@@ -51951,6 +57683,8 @@
</description>
</method>
<method name="rename_variable">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="new_name" type="String">
@@ -51959,6 +57693,8 @@
</description>
</method>
<method name="sequence_connect">
+ <return type="void">
+ </return>
<argument index="0" name="func" type="String">
</argument>
<argument index="1" name="from_node" type="int">
@@ -51971,6 +57707,8 @@
</description>
</method>
<method name="sequence_disconnect">
+ <return type="void">
+ </return>
<argument index="0" name="func" type="String">
</argument>
<argument index="1" name="from_node" type="int">
@@ -51983,20 +57721,26 @@
</description>
</method>
<method name="set_function_scroll">
- <argument index="0" name="ofs" type="String">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="arg1" type="Vector2">
+ <argument index="1" name="ofs" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_instance_base_type">
+ <return type="void">
+ </return>
<argument index="0" name="type" type="String">
</argument>
<description>
</description>
</method>
<method name="set_node_pos">
+ <return type="void">
+ </return>
<argument index="0" name="func" type="String">
</argument>
<argument index="1" name="id" type="int">
@@ -52007,6 +57751,8 @@
</description>
</method>
<method name="set_variable_default_value">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="value" type="Variant">
@@ -52015,6 +57761,8 @@
</description>
</method>
<method name="set_variable_export">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="enable" type="bool">
@@ -52023,6 +57771,8 @@
</description>
</method>
<method name="set_variable_info">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<argument index="1" name="value" type="Dictionary">
@@ -52055,7 +57805,7 @@
</description>
<methods>
<method name="get_basic_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
@@ -52067,12 +57817,16 @@
</description>
</method>
<method name="set_basic_type">
- <argument index="0" name="name" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
<method name="set_basic_type_constant">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -52080,9 +57834,9 @@
</method>
</methods>
<members>
- <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
+ <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="" enum="Variant.Type">
</member>
- <member name="constant" type="String" setter="set_basic_type_constant" getter="get_basic_type_constant" brief="">
+ <member name="constant/constant" type="String" setter="set_basic_type_constant" getter="get_basic_type_constant" brief="">
</member>
</members>
<constants>
@@ -52095,20 +57849,22 @@
</description>
<methods>
<method name="get_func">
- <return type="int">
+ <return type="int" enum="VisualScriptBuiltinFunc.BuiltinFunc">
</return>
<description>
</description>
</method>
<method name="set_func">
- <argument index="0" name="which" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="which" type="int" enum="VisualScriptBuiltinFunc.BuiltinFunc">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="function" type="int" setter="set_func" getter="get_func" brief="">
+ <member name="function" type="int" setter="set_func" getter="get_func" brief="" enum="VisualScriptBuiltinFunc.BuiltinFunc">
</member>
</members>
<constants>
@@ -52133,12 +57889,16 @@
</description>
</method>
<method name="set_base_type">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="set_class_constant">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -52148,7 +57908,7 @@
<members>
<member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="constant" type="String" setter="set_class_constant" getter="get_class_constant" brief="">
+ <member name="constant/constant" type="String" setter="set_class_constant" getter="get_class_constant" brief="">
</member>
</members>
<constants>
@@ -52179,18 +57939,24 @@
</description>
</method>
<method name="set_description">
+ <return type="void">
+ </return>
<argument index="0" name="description" type="String">
</argument>
<description>
</description>
</method>
<method name="set_size">
+ <return type="void">
+ </return>
<argument index="0" name="size" type="Vector2">
</argument>
<description>
</description>
</method>
<method name="set_title">
+ <return type="void">
+ </return>
<argument index="0" name="title" type="String">
</argument>
<description>
@@ -52225,7 +57991,7 @@
</description>
<methods>
<method name="get_constant_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
@@ -52237,12 +58003,16 @@
</description>
</method>
<method name="set_constant_type">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
<method name="set_constant_value">
+ <return type="void">
+ </return>
<argument index="0" name="value" type="Variant">
</argument>
<description>
@@ -52250,9 +58020,9 @@
</method>
</methods>
<members>
- <member name="type" type="int" setter="set_constant_type" getter="get_constant_type" brief="">
+ <member name="type" type="int" setter="set_constant_type" getter="get_constant_type" brief="" enum="Variant.Type">
</member>
- <member name="value" type="Nil" setter="set_constant_value" getter="get_constant_value" brief="">
+ <member name="value" type="Variant" setter="set_constant_value" getter="get_constant_value" brief="">
</member>
</members>
<constants>
@@ -52271,19 +58041,23 @@
</description>
</method>
<method name="get_constructor_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="set_constructor">
+ <return type="void">
+ </return>
<argument index="0" name="constructor" type="Dictionary">
</argument>
<description>
</description>
</method>
<method name="set_constructor_type">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
@@ -52292,7 +58066,7 @@
<members>
<member name="constructor" type="Dictionary" setter="set_constructor" getter="get_constructor" brief="">
</member>
- <member name="type" type="int" setter="set_constructor_type" getter="get_constructor_type" brief="">
+ <member name="type" type="int" setter="set_constructor_type" getter="get_constructor_type" brief="" enum="Variant.Type">
</member>
</members>
<constants>
@@ -52414,15 +58188,15 @@
</constant>
<constant name="START_MODE_RESUME_YIELD" value="2">
</constant>
- <constant name="STEP_PUSH_STACK_BIT" value="16777216">
+ <constant name="STEP_PUSH_STACK_BIT" value="16777216" enum="">
</constant>
- <constant name="STEP_GO_BACK_BIT" value="33554432">
+ <constant name="STEP_GO_BACK_BIT" value="33554432" enum="">
</constant>
- <constant name="STEP_NO_ADVANCE_BIT" value="67108864">
+ <constant name="STEP_NO_ADVANCE_BIT" value="67108864" enum="">
</constant>
- <constant name="STEP_EXIT_FUNCTION_BIT" value="134217728">
+ <constant name="STEP_EXIT_FUNCTION_BIT" value="134217728" enum="">
</constant>
- <constant name="STEP_YIELD_BIT" value="268435456">
+ <constant name="STEP_YIELD_BIT" value="268435456" enum="">
</constant>
</constants>
</class>
@@ -52433,13 +58207,15 @@
</description>
<methods>
<method name="get_deconstruct_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="set_deconstruct_type">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
@@ -52448,7 +58224,7 @@
<members>
<member name="elem_cache" type="Array" setter="_set_elem_cache" getter="_get_elem_cache" brief="">
</member>
- <member name="type" type="int" setter="set_deconstruct_type" getter="get_deconstruct_type" brief="">
+ <member name="type" type="int" setter="set_deconstruct_type" getter="get_deconstruct_type" brief="" enum="Variant.Type">
</member>
</members>
<constants>
@@ -52467,6 +58243,8 @@
</description>
</method>
<method name="set_signal">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -52493,6 +58271,8 @@
</description>
</method>
<method name="set_singleton">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -52500,7 +58280,7 @@
</method>
</methods>
<members>
- <member name="constant" type="String" setter="set_singleton" getter="get_singleton" brief="">
+ <member name="constant/constant" type="String" setter="set_singleton" getter="get_singleton" brief="">
</member>
</members>
<constants>
@@ -52551,13 +58331,13 @@
</description>
</method>
<method name="get_basic_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="get_call_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="VisualScriptFunctionCall.CallMode">
</return>
<description>
</description>
@@ -52569,7 +58349,7 @@
</description>
</method>
<method name="get_rpc_call_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="VisualScriptFunctionCall.RPCCallMode">
</return>
<description>
</description>
@@ -52593,60 +58373,80 @@
</description>
</method>
<method name="set_base_path">
+ <return type="void">
+ </return>
<argument index="0" name="base_path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_base_script">
+ <return type="void">
+ </return>
<argument index="0" name="base_script" type="String">
</argument>
<description>
</description>
</method>
<method name="set_base_type">
+ <return type="void">
+ </return>
<argument index="0" name="base_type" type="String">
</argument>
<description>
</description>
</method>
<method name="set_basic_type">
- <argument index="0" name="basic_type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="basic_type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
<method name="set_call_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="VisualScriptFunctionCall.CallMode">
</argument>
<description>
</description>
</method>
<method name="set_function">
+ <return type="void">
+ </return>
<argument index="0" name="function" type="String">
</argument>
<description>
</description>
</method>
<method name="set_rpc_call_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="VisualScriptFunctionCall.RPCCallMode">
</argument>
<description>
</description>
</method>
<method name="set_singleton">
+ <return type="void">
+ </return>
<argument index="0" name="singleton" type="String">
</argument>
<description>
</description>
</method>
<method name="set_use_default_args">
+ <return type="void">
+ </return>
<argument index="0" name="amount" type="int">
</argument>
<description>
</description>
</method>
<method name="set_validate">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
@@ -52660,15 +58460,15 @@
</member>
<member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
+ <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="" enum="Variant.Type">
</member>
- <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="" enum="VisualScriptFunctionCall.CallMode">
</member>
<member name="function" type="String" setter="set_function" getter="get_function" brief="">
</member>
<member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
- <member name="rpc_call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" brief="">
+ <member name="rpc_call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" brief="" enum="VisualScriptFunctionCall.RPCCallMode">
</member>
<member name="singleton" type="String" setter="set_singleton" getter="get_singleton" brief="">
</member>
@@ -52695,6 +58495,8 @@
</description>
<methods>
<method name="connect_to_signal">
+ <return type="void">
+ </return>
<argument index="0" name="obj" type="Object">
</argument>
<argument index="1" name="signals" type="String">
@@ -52711,9 +58513,9 @@
</description>
</method>
<method name="resume">
- <return type="Array">
+ <return type="Variant">
</return>
- <argument index="0" name="args" type="Array" default="NULL">
+ <argument index="0" name="args" type="Array" default="null">
</argument>
<description>
</description>
@@ -52735,6 +58537,8 @@
</description>
</method>
<method name="set_global_constant">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="int">
</argument>
<description>
@@ -52742,7 +58546,7 @@
</method>
</methods>
<members>
- <member name="constant" type="int" setter="set_global_constant" getter="get_global_constant" brief="">
+ <member name="constant/constant" type="int" setter="set_global_constant" getter="get_global_constant" brief="">
</member>
</members>
<constants>
@@ -52775,7 +58579,7 @@
</description>
<methods>
<method name="get_action_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="VisualScriptInputAction.Mode">
</return>
<description>
</description>
@@ -52787,12 +58591,16 @@
</description>
</method>
<method name="set_action_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="VisualScriptInputAction.Mode">
</argument>
<description>
</description>
</method>
<method name="set_action_name">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -52802,7 +58610,7 @@
<members>
<member name="action" type="String" setter="set_action_name" getter="get_action_name" brief="">
</member>
- <member name="mode" type="int" setter="set_action_mode" getter="get_action_mode" brief="">
+ <member name="mode" type="int" setter="set_action_mode" getter="get_action_mode" brief="" enum="VisualScriptInputAction.Mode">
</member>
</members>
<constants>
@@ -52831,26 +58639,30 @@
</description>
</method>
<method name="get_var_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="set_var_name">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="set_var_type">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="type" type="int" setter="set_var_type" getter="get_var_type" brief="">
+ <member name="type" type="int" setter="set_var_type" getter="get_var_type" brief="" enum="Variant.Type">
</member>
<member name="var_name" type="String" setter="set_var_name" getter="get_var_name" brief="">
</member>
@@ -52871,26 +58683,30 @@
</description>
</method>
<method name="get_var_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="set_var_name">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
</description>
</method>
<method name="set_var_type">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="type" type="int" setter="set_var_type" getter="get_var_type" brief="">
+ <member name="type" type="int" setter="set_var_type" getter="get_var_type" brief="" enum="Variant.Type">
</member>
<member name="var_name" type="String" setter="set_var_name" getter="get_var_name" brief="">
</member>
@@ -52905,20 +58721,22 @@
</description>
<methods>
<method name="get_math_constant">
- <return type="int">
+ <return type="int" enum="VisualScriptMathConstant.MathConstant">
</return>
<description>
</description>
</method>
<method name="set_math_constant">
- <argument index="0" name="which" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="which" type="int" enum="VisualScriptMathConstant.MathConstant">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="constant" type="int" setter="set_math_constant" getter="get_math_constant" brief="">
+ <member name="constant/constant" type="int" setter="set_math_constant" getter="get_math_constant" brief="" enum="VisualScriptMathConstant.MathConstant">
</member>
</members>
<constants>
@@ -52945,6 +58763,8 @@
</description>
</method>
<method name="set_default_input_value">
+ <return type="void">
+ </return>
<argument index="0" name="port_idx" type="int">
</argument>
<argument index="1" name="value" type="Variant">
@@ -52973,34 +58793,38 @@
</description>
<methods>
<method name="get_operator" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Operator">
</return>
<description>
</description>
</method>
<method name="get_typed" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="set_operator">
- <argument index="0" name="op" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="op" type="int" enum="Variant.Operator">
</argument>
<description>
</description>
</method>
<method name="set_typed">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="operator" type="int" setter="set_operator" getter="get_operator" brief="">
+ <member name="operator" type="int" setter="set_operator" getter="get_operator" brief="" enum="Variant.Operator">
</member>
- <member name="type" type="int" setter="set_typed" getter="get_typed" brief="">
+ <member name="type" type="int" setter="set_typed" getter="get_typed" brief="" enum="Variant.Type">
</member>
</members>
<constants>
@@ -53013,13 +58837,15 @@
</description>
<methods>
<method name="get_preload" qualifiers="const">
- <return type="Object">
+ <return type="Resource">
</return>
<description>
</description>
</method>
<method name="set_preload">
- <argument index="0" name="resource" type="Object">
+ <return type="void">
+ </return>
+ <argument index="0" name="resource" type="Resource">
</argument>
<description>
</description>
@@ -53057,13 +58883,13 @@
</description>
</method>
<method name="get_basic_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="get_call_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="VisualScriptPropertyGet.CallMode">
</return>
<description>
</description>
@@ -53081,42 +58907,56 @@
</description>
</method>
<method name="set_base_path">
+ <return type="void">
+ </return>
<argument index="0" name="base_path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_base_script">
+ <return type="void">
+ </return>
<argument index="0" name="base_script" type="String">
</argument>
<description>
</description>
</method>
<method name="set_base_type">
+ <return type="void">
+ </return>
<argument index="0" name="base_type" type="String">
</argument>
<description>
</description>
</method>
<method name="set_basic_type">
- <argument index="0" name="basic_type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="basic_type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
<method name="set_call_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="VisualScriptPropertyGet.CallMode">
</argument>
<description>
</description>
</method>
<method name="set_index">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="String">
</argument>
<description>
</description>
</method>
<method name="set_property">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<description>
@@ -53128,7 +58968,7 @@
</member>
<member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
+ <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="" enum="Variant.Type">
</member>
<member name="index" type="String" setter="set_index" getter="get_index" brief="">
</member>
@@ -53136,9 +58976,9 @@
</member>
<member name="property" type="String" setter="set_property" getter="get_property" brief="">
</member>
- <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="" enum="VisualScriptPropertyGet.CallMode">
</member>
- <member name="type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" brief="">
+ <member name="type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" brief="" enum="Variant.Type">
</member>
</members>
<constants>
@@ -53157,7 +58997,7 @@
</description>
<methods>
<method name="get_assign_op" qualifiers="const">
- <return type="int">
+ <return type="int" enum="VisualScriptPropertySet.AssignOp">
</return>
<description>
</description>
@@ -53181,13 +59021,13 @@
</description>
</method>
<method name="get_basic_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="get_call_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="VisualScriptPropertySet.CallMode">
</return>
<description>
</description>
@@ -53205,48 +59045,64 @@
</description>
</method>
<method name="set_assign_op">
- <argument index="0" name="assign_op" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="assign_op" type="int" enum="VisualScriptPropertySet.AssignOp">
</argument>
<description>
</description>
</method>
<method name="set_base_path">
+ <return type="void">
+ </return>
<argument index="0" name="base_path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_base_script">
+ <return type="void">
+ </return>
<argument index="0" name="base_script" type="String">
</argument>
<description>
</description>
</method>
<method name="set_base_type">
+ <return type="void">
+ </return>
<argument index="0" name="base_type" type="String">
</argument>
<description>
</description>
</method>
<method name="set_basic_type">
- <argument index="0" name="basic_type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="basic_type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
<method name="set_call_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="VisualScriptPropertySet.CallMode">
</argument>
<description>
</description>
</method>
<method name="set_index">
+ <return type="void">
+ </return>
<argument index="0" name="index" type="String">
</argument>
<description>
</description>
</method>
<method name="set_property">
+ <return type="void">
+ </return>
<argument index="0" name="property" type="String">
</argument>
<description>
@@ -53254,13 +59110,13 @@
</method>
</methods>
<members>
- <member name="assign_op" type="int" setter="set_assign_op" getter="get_assign_op" brief="">
+ <member name="assign_op" type="int" setter="set_assign_op" getter="get_assign_op" brief="" enum="VisualScriptPropertySet.AssignOp">
</member>
<member name="base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
</member>
<member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
+ <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="" enum="Variant.Type">
</member>
<member name="index" type="String" setter="set_index" getter="get_index" brief="">
</member>
@@ -53268,9 +59124,9 @@
</member>
<member name="property" type="String" setter="set_property" getter="get_property" brief="">
</member>
- <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="" enum="VisualScriptPropertySet.CallMode">
</member>
- <member name="type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" brief="">
+ <member name="type_cache" type="Dictionary" setter="_set_type_cache" getter="_get_type_cache" brief="">
</member>
</members>
<constants>
@@ -53295,6 +59151,8 @@
</description>
</method>
<method name="set_resource_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
@@ -53315,7 +59173,7 @@
</description>
<methods>
<method name="get_return_type" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
@@ -53327,13 +59185,17 @@
</description>
</method>
<method name="set_enable_return_value">
+ <return type="void">
+ </return>
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_return_type">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
@@ -53342,7 +59204,7 @@
<members>
<member name="return_enabled" type="bool" setter="set_enable_return_value" getter="is_return_value_enabled" brief="">
</member>
- <member name="return_type" type="int" setter="set_return_type" getter="get_return_type" brief="">
+ <member name="return_type" type="int" setter="set_return_type" getter="get_return_type" brief="" enum="Variant.Type">
</member>
</members>
<constants>
@@ -53361,6 +59223,8 @@
</description>
</method>
<method name="set_node_path">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="NodePath">
</argument>
<description>
@@ -53391,20 +59255,22 @@
</description>
<methods>
<method name="get_typed" qualifiers="const">
- <return type="int">
+ <return type="int" enum="Variant.Type">
</return>
<description>
</description>
</method>
<method name="set_typed">
- <argument index="0" name="type" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Variant.Type">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="type" type="int" setter="set_typed" getter="get_typed" brief="">
+ <member name="type" type="int" setter="set_typed" getter="get_typed" brief="" enum="Variant.Type">
</member>
</members>
<constants>
@@ -53433,6 +59299,8 @@
</description>
</method>
<method name="set_steps">
+ <return type="void">
+ </return>
<argument index="0" name="steps" type="int">
</argument>
<description>
@@ -53453,6 +59321,8 @@
</description>
<methods>
<method name="_subcall" qualifiers="virtual">
+ <return type="Variant">
+ </return>
<argument index="0" name="arguments" type="Variant">
</argument>
<description>
@@ -53491,12 +59361,16 @@
</description>
</method>
<method name="set_base_script">
+ <return type="void">
+ </return>
<argument index="0" name="path" type="String">
</argument>
<description>
</description>
</method>
<method name="set_base_type">
+ <return type="void">
+ </return>
<argument index="0" name="type" type="String">
</argument>
<description>
@@ -53525,6 +59399,8 @@
</description>
</method>
<method name="set_variable">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -53551,6 +59427,8 @@
</description>
</method>
<method name="set_variable">
+ <return type="void">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -53587,26 +59465,30 @@
</description>
</method>
<method name="get_yield_mode">
- <return type="int">
+ <return type="int" enum="VisualScriptYield.YieldMode">
</return>
<description>
</description>
</method>
<method name="set_wait_time">
+ <return type="void">
+ </return>
<argument index="0" name="sec" type="float">
</argument>
<description>
</description>
</method>
<method name="set_yield_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="VisualScriptYield.YieldMode">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="mode" type="int" setter="set_yield_mode" getter="get_yield_mode" brief="">
+ <member name="mode" type="int" setter="set_yield_mode" getter="get_yield_mode" brief="" enum="VisualScriptYield.YieldMode">
</member>
<member name="wait_time" type="float" setter="set_wait_time" getter="get_wait_time" brief="">
</member>
@@ -53639,7 +59521,7 @@
</description>
</method>
<method name="get_call_mode" qualifiers="const">
- <return type="int">
+ <return type="int" enum="VisualScriptYieldSignal.CallMode">
</return>
<description>
</description>
@@ -53651,24 +59533,32 @@
</description>
</method>
<method name="set_base_path">
+ <return type="void">
+ </return>
<argument index="0" name="base_path" type="NodePath">
</argument>
<description>
</description>
</method>
<method name="set_base_type">
+ <return type="void">
+ </return>
<argument index="0" name="base_type" type="String">
</argument>
<description>
</description>
</method>
<method name="set_call_mode">
- <argument index="0" name="mode" type="int">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="VisualScriptYieldSignal.CallMode">
</argument>
<description>
</description>
</method>
<method name="set_signal">
+ <return type="void">
+ </return>
<argument index="0" name="signal" type="String">
</argument>
<description>
@@ -53678,7 +59568,7 @@
<members>
<member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="" enum="VisualScriptYieldSignal.CallMode">
</member>
<member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
@@ -53703,6 +59593,12 @@
The visual server is completely opaque, the internals are entirely implementation specific and cannot be accessed.
</description>
<methods>
+ <method name="force_draw">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="texture_create">
<return type="RID">
</return>
@@ -53712,9 +59608,9 @@
<method name="texture_create_from_image">
<return type="RID">
</return>
- <argument index="0" name="arg0" type="Object">
+ <argument index="0" name="image" type="Image">
</argument>
- <argument index="1" name="arg1" type="int" default="7">
+ <argument index="1" name="flags" type="int" default="7">
</argument>
<description>
</description>
@@ -53722,7 +59618,7 @@
<method name="texture_get_flags" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="arg0" type="RID">
+ <argument index="0" name="texture" type="RID">
</argument>
<description>
</description>
@@ -53730,7 +59626,7 @@
<method name="texture_get_height" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="arg0" type="RID">
+ <argument index="0" name="texture" type="RID">
</argument>
<description>
</description>
@@ -53738,20 +59634,24 @@
<method name="texture_get_width" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="arg0" type="RID">
+ <argument index="0" name="texture" type="RID">
</argument>
<description>
</description>
</method>
<method name="texture_set_flags">
- <argument index="0" name="arg0" type="RID">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="RID">
</argument>
- <argument index="1" name="arg1" type="int">
+ <argument index="1" name="flags" type="int">
</argument>
<description>
</description>
</method>
<method name="texture_set_shrink_all_x2_on_set_data">
+ <return type="void">
+ </return>
<argument index="0" name="shrink" type="bool">
</argument>
<description>
@@ -53770,7 +59670,7 @@
</description>
<methods>
<method name="get_ref" qualifiers="const">
- <return type="Object">
+ <return type="Variant">
</return>
<description>
Returns the [Object] this weakref is referring to.
@@ -53809,12 +59709,16 @@
</description>
</method>
<method name="set_resizable">
+ <return type="void">
+ </return>
<argument index="0" name="resizable" type="bool">
</argument>
<description>
</description>
</method>
<method name="set_title">
+ <return type="void">
+ </return>
<argument index="0" name="title" type="String">
</argument>
<description>
@@ -53890,12 +59794,16 @@
</description>
</method>
<method name="set_environment">
+ <return type="void">
+ </return>
<argument index="0" name="env" type="Environment">
</argument>
<description>
</description>
</method>
<method name="set_fallback_environment">
+ <return type="void">
+ </return>
<argument index="0" name="env" type="Environment">
</argument>
<description>
@@ -53960,6 +59868,8 @@
</description>
</method>
<method name="set_environment">
+ <return type="void">
+ </return>
<argument index="0" name="env" type="Environment">
</argument>
<description>
@@ -54054,7 +59964,7 @@
</description>
</method>
<method name="get_node_type">
- <return type="int">
+ <return type="int" enum="XMLParser.NodeType">
</return>
<description>
Get the type of the current node. Compare with [code]NODE_*[/code] constants.
@@ -54077,7 +59987,7 @@
</description>
</method>
<method name="open">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="file" type="String">
</argument>
@@ -54086,7 +59996,7 @@
</description>
</method>
<method name="open_buffer">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="buffer" type="PoolByteArray">
</argument>
@@ -54095,14 +60005,14 @@
</description>
</method>
<method name="read">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<description>
Read the next node of the file. This returns an error code.
</description>
</method>
<method name="seek">
- <return type="int">
+ <return type="int" enum="Error">
</return>
<argument index="0" name="pos" type="int">
</argument>
@@ -54111,6 +60021,8 @@
</description>
</method>
<method name="skip_section">
+ <return type="void">
+ </return>
<description>
Skips the current section. If the node contains other elements, they will be ignored and the cursor will go to the closing of the current element.
</description>
@@ -54156,6 +60068,8 @@
</description>
</method>
<method name="set_sort_enabled">
+ <return type="void">
+ </return>
<argument index="0" name="enabled" type="bool">
</argument>
<description>
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 40c66b0bc5..216100bac6 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -31,6 +31,7 @@
#ifdef ALSA_ENABLED
+#include "os/os.h"
#include "project_settings.h"
#include <errno.h>
@@ -44,7 +45,7 @@ Error AudioDriverALSA::init() {
samples_in = NULL;
samples_out = NULL;
- mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
+ mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
@@ -86,19 +87,25 @@ Error AudioDriverALSA::init() {
status = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &mix_rate, NULL);
CHECK_FAIL(status < 0);
- int latency = GLOBAL_DEF("audio/output_latency", 25);
- buffer_size = closest_power_of_2(latency * mix_rate / 1000);
+ // In ALSA the period size seems to be the one that will determine the actual latency
+ // Ref: https://www.alsa-project.org/main/index.php/FramesPeriods
+ unsigned int periods = 2;
+ int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
+ buffer_size = buffer_frames * periods;
+ period_size = buffer_frames;
// set buffer size from project settings
status = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size);
CHECK_FAIL(status < 0);
- // make period size 1/8
- period_size = buffer_size >> 3;
status = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &period_size, NULL);
CHECK_FAIL(status < 0);
- unsigned int periods = 2;
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_line("audio buffer frames: " + itos(period_size) + " calculated latency: " + itos(period_size * 1000 / mix_rate) + "ms");
+ }
+
status = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &periods, NULL);
CHECK_FAIL(status < 0);
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index 83601be41b..c76ec0da61 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -51,6 +51,7 @@ class AudioDriverALSA : public AudioDriver {
unsigned int mix_rate;
SpeakerMode speaker_mode;
+ snd_pcm_uframes_t buffer_frames;
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
int channels;
diff --git a/drivers/convex_decomp/b2d_decompose.cpp b/drivers/convex_decomp/b2d_decompose.cpp
index 14ab4d1072..97d312983f 100644
--- a/drivers/convex_decomp/b2d_decompose.cpp
+++ b/drivers/convex_decomp/b2d_decompose.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* b2d_decompose.cpp */
+/* b2d_decompose.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 74e844836e..ff0741f425 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -574,6 +574,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
Rect2 src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
+ Rect2 dst_rect = Rect2(rect->rect.position, rect->rect.size);
if (rect->flags & CANVAS_RECT_FLIP_H) {
src_rect.size.x *= -1;
@@ -584,12 +585,12 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
}
if (rect->flags & CANVAS_RECT_TRANSPOSE) {
- //err..
+ dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform
}
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y));
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y));
state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, (rect->flags & CANVAS_RECT_CLIP_UV) ? true : false);
@@ -1214,11 +1215,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
last_blend_mode = blend_mode;
}
- state.canvas_item_modulate = unshaded ? ci->final_modulate : Color(
- ci->final_modulate.r * p_modulate.r,
- ci->final_modulate.g * p_modulate.g,
- ci->final_modulate.b * p_modulate.b,
- ci->final_modulate.a * p_modulate.a);
+ state.canvas_item_modulate = unshaded ? ci->final_modulate : Color(ci->final_modulate.r * p_modulate.r, ci->final_modulate.g * p_modulate.g, ci->final_modulate.b * p_modulate.b, ci->final_modulate.a * p_modulate.a);
state.final_transform = ci->final_transform;
state.extra_matrix = Transform2D();
@@ -1287,6 +1284,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
case VS::CANVAS_LIGHT_FILTER_NONE: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, true); break;
case VS::CANVAS_LIGHT_FILTER_PCF3: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, true); break;
case VS::CANVAS_LIGHT_FILTER_PCF5: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, true); break;
+ case VS::CANVAS_LIGHT_FILTER_PCF7: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, true); break;
case VS::CANVAS_LIGHT_FILTER_PCF9: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, true); break;
case VS::CANVAS_LIGHT_FILTER_PCF13: state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, true); break;
}
@@ -1337,6 +1335,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, false);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 9c7a1dd859..6bef039dd1 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* rasterizer_storage_gles3.cpp */
+/* rasterizer_scene_gles3.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -247,7 +247,7 @@ bool RasterizerSceneGLES3::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas,
int qidx = p_in_quadrants[i];
- if (shadow_atlas->quadrants[qidx].subdivision == p_current_subdiv) {
+ if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) {
return false;
}
@@ -257,7 +257,7 @@ bool RasterizerSceneGLES3::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas,
int found_free_idx = -1; //found a free one
int found_used_idx = -1; //found existing one, must steal it
- uint64_t min_pass; // pass of the existing one, try to use the least recently used one (LRU fashion)
+ uint64_t min_pass = 0; // pass of the existing one, try to use the least recently used one (LRU fashion)
for (int j = 0; j < sc; j++) {
if (!sarr[j].owner.is_valid()) {
@@ -349,7 +349,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK;
- bool should_realloc = shadow_atlas->quadrants[q].subdivision != best_subdiv && (shadow_atlas->quadrants[q].shadows[s].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec);
+ bool should_realloc = shadow_atlas->quadrants[q].subdivision != (uint32_t)best_subdiv && (shadow_atlas->quadrants[q].shadows[s].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec);
bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version;
if (!should_realloc) {
@@ -554,7 +554,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas, int
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
ERR_FAIL_COND(!reflection_atlas);
- uint32_t subdiv = next_power_of_2(p_subdiv);
+ int subdiv = next_power_of_2(p_subdiv);
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
subdiv <<= 1;
}
@@ -1100,15 +1100,15 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
state.current_line_width = p_material->line_width;
}
- if (state.current_depth_test != (!p_material->shader->spatial.ontop)) {
- if (p_material->shader->spatial.ontop) {
+ if (state.current_depth_test != (!p_material->shader->spatial.no_depth_test)) {
+ if (p_material->shader->spatial.no_depth_test) {
glDisable(GL_DEPTH_TEST);
} else {
glEnable(GL_DEPTH_TEST);
}
- state.current_depth_test = !p_material->shader->spatial.ontop;
+ state.current_depth_test = !p_material->shader->spatial.no_depth_test;
}
if (state.current_depth_draw != p_material->shader->spatial.depth_draw_mode) {
@@ -2195,7 +2195,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow) {
bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture;
- bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || p_material->shader->spatial.ontop;
+ bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX;
bool has_alpha = has_base_alpha || has_blend_alpha;
bool shadow = false;
@@ -2267,7 +2267,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
}
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
- e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_DEPTH_LAYER_SHIFT;
+ e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
if (!has_blend_alpha && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
@@ -2283,6 +2283,8 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
if (e->instance->gi_probe_instances.size()) {
e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
}
+
+ e->sort_key |= uint64_t(p_material->render_priority + 128) << RenderList::SORT_KEY_PRIORITY_SHIFT;
}
/*
@@ -2700,7 +2702,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK;
- ERR_CONTINUE(shadow >= shadow_atlas->quadrants[quadrant].shadows.size());
+ ERR_CONTINUE(shadow >= (uint32_t)shadow_atlas->quadrants[quadrant].shadows.size());
uint32_t atlas_size = shadow_atlas->size;
uint32_t quadrant_size = atlas_size >> 1;
@@ -2787,7 +2789,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK;
- ERR_CONTINUE(shadow >= shadow_atlas->quadrants[quadrant].shadows.size());
+ ERR_CONTINUE(shadow >= (uint32_t)shadow_atlas->quadrants[quadrant].shadows.size());
uint32_t atlas_size = shadow_atlas->size;
uint32_t quadrant_size = atlas_size >> 1;
@@ -3259,6 +3261,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
GLint axis[2] = { i, 1 - i };
glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::AXIS), 1, axis);
+ glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::SCREEN_SIZE), 1, ss);
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[i]);
glActiveTexture(GL_TEXTURE1);
@@ -4280,7 +4284,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glEnable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
- render_list.sort_by_reverse_depth(true);
+ render_list.sort_by_reverse_depth_and_priority(true);
if (state.directional_light_count == 0) {
directional_light = NULL;
@@ -4443,9 +4447,10 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
}
}
+ float bias_mult = Math::lerp(1.0f, light_instance->shadow_transform[p_pass].bias_scale, light->param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE]);
zfar = light->param[VS::LIGHT_PARAM_RANGE];
- bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS] * light_instance->shadow_transform[p_pass].bias_scale;
- normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[p_pass].bias_scale;
+ bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS] * bias_mult;
+ normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * bias_mult;
fbo = directional_shadow.fbo;
vp_height = directional_shadow.size;
@@ -4464,7 +4469,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK;
- ERR_FAIL_INDEX(shadow, shadow_atlas->quadrants[quadrant].shadows.size());
+ ERR_FAIL_INDEX((int)shadow, shadow_atlas->quadrants[quadrant].shadows.size());
uint32_t quadrant_size = shadow_atlas->size >> 1;
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 1ab2afe664..5503dba5c4 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -108,7 +108,7 @@ public:
TonemapShaderGLES3 tonemap_shader;
struct SceneDataUBO {
-
+ //this is a std140 compatible struct. Please read the OpenGL 3.3 Specificaiton spec before doing any changes
float projection_matrix[16];
float camera_inverse_matrix[16];
float camera_matrix[16];
@@ -133,12 +133,12 @@ public:
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
- bool fog_depth_enabled;
+ uint32_t fog_depth_enabled;
float fog_depth_begin;
float fog_depth_curve;
- bool fog_transmit_enabled;
+ uint32_t fog_transmit_enabled;
float fog_transmit_curve;
- bool fog_height_enabled;
+ uint32_t fog_height_enabled;
float fog_height_min;
float fog_height_max;
float fog_height_curve;
@@ -244,7 +244,7 @@ public:
GLuint fbo_id[6];
GLuint cubemap;
- int size;
+ uint32_t size;
};
Vector<ShadowCubeMap> shadow_cubemaps;
@@ -531,7 +531,7 @@ public:
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture);
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness);
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_radius2, float p_intensity2, float p_intensity, float p_bias, float p_light_affect, const Color &p_color, bool p_blur);
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur);
virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
@@ -645,17 +645,25 @@ public:
MAX_LIGHTS = 4096,
MAX_REFLECTIONS = 1024,
- SORT_KEY_DEPTH_LAYER_SHIFT = 60,
+ SORT_KEY_PRIORITY_SHIFT = 56,
+ SORT_KEY_PRIORITY_MASK = 0xFF,
+ //depth layer for opaque (56-52)
+ SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT = 52,
+ SORT_KEY_OPAQUE_DEPTH_LAYER_MASK = 0xF,
//64 bits unsupported in MSVC
-#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 59)
-#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 58)
-#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 57)
-#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 56)
- SORT_KEY_SHADING_SHIFT = 56,
+#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 51)
+#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 50)
+#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 49)
+#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 48)
+ SORT_KEY_SHADING_SHIFT = 48,
SORT_KEY_SHADING_MASK = 15,
- SORT_KEY_MATERIAL_INDEX_SHIFT = 40,
- SORT_KEY_GEOMETRY_INDEX_SHIFT = 20,
- SORT_KEY_GEOMETRY_TYPE_SHIFT = 15,
+ //48-32 material index
+ SORT_KEY_MATERIAL_INDEX_SHIFT = 32,
+ //32-12 geometry index
+ SORT_KEY_GEOMETRY_INDEX_SHIFT = 12,
+ //bits 12-8 geometry type
+ SORT_KEY_GEOMETRY_TYPE_SHIFT = 8,
+ //bits 0-7 for flags
SORT_KEY_CULL_DISABLED_FLAG = 4,
SORT_KEY_SKELETON_FLAG = 2,
SORT_KEY_MIRROR_FLAG = 1
@@ -721,16 +729,22 @@ public:
}
}
- struct SortByReverseDepth {
+ struct SortByReverseDepthAndPriority {
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- return A->instance->depth > B->instance->depth;
+ uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT);
+ uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT);
+ if (layer_A == layer_B) {
+ return A->instance->depth > B->instance->depth;
+ } else {
+ return layer_A < layer_B;
+ }
}
};
- void sort_by_reverse_depth(bool p_alpha) { //used for alpha
+ void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
- SortArray<Element *, SortByReverseDepth> sorter;
+ SortArray<Element *, SortByReverseDepthAndPriority> sorter;
if (p_alpha) {
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
} else {
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index c5c9140874..91ba3aa702 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1599,7 +1599,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.uses_alpha_scissor = false;
p_shader->spatial.uses_discard = false;
p_shader->spatial.unshaded = false;
- p_shader->spatial.ontop = false;
+ p_shader->spatial.no_depth_test = false;
p_shader->spatial.uses_sss = false;
p_shader->spatial.uses_vertex_lighting = false;
p_shader->spatial.uses_screen_texture = false;
@@ -1621,7 +1621,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_DISABLED);
shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded;
- shaders.actions_scene.render_mode_flags["ontop"] = &p_shader->spatial.ontop;
+ shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test;
shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
@@ -1948,6 +1948,17 @@ void RasterizerStorageGLES3::material_remove_instance_owner(RID p_material, Rast
}
}
+void RasterizerStorageGLES3::material_set_render_priority(RID p_material, int priority) {
+
+ ERR_FAIL_COND(priority < VS::MATERIAL_RENDER_PRIORITY_MIN);
+ ERR_FAIL_COND(priority > VS::MATERIAL_RENDER_PRIORITY_MAX);
+
+ Material *material = material_owner.get(p_material);
+ ERR_FAIL_COND(!material);
+
+ material->render_priority = priority;
+}
+
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant &value, uint8_t *data, bool p_linear_color) {
switch (type) {
case ShaderLanguage::TYPE_BOOL: {
@@ -3963,7 +3974,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int
ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color());
int stride = multimesh->color_floats + multimesh->xform_floats;
- float *dataptr = &multimesh->data[stride * p_index + multimesh->color_floats];
+ float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats];
if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
union {
@@ -3971,6 +3982,8 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int
float colf;
} cu;
+ cu.colf = dataptr[0];
+
return Color::hex(BSWAP32(cu.colu));
} else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) {
@@ -4448,6 +4461,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) {
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1;
+ light->param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1;
light->color = Color(1, 1, 1, 1);
light->shadow = false;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index c74b127b23..f75b77aabe 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -444,7 +444,7 @@ public:
bool uses_alpha;
bool uses_alpha_scissor;
bool unshaded;
- bool ontop;
+ bool no_depth_test;
bool uses_vertex;
bool uses_discard;
bool uses_sss;
@@ -502,6 +502,7 @@ public:
SelfList<Material> dirty_list;
Vector<RID> textures;
float line_width;
+ int render_priority;
RID next_pass;
@@ -523,6 +524,7 @@ public:
ubo_id = 0;
ubo_size = 0;
last_pass = 0;
+ render_priority = 0;
}
};
@@ -550,6 +552,8 @@ public:
virtual void material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance);
virtual void material_remove_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance);
+ virtual void material_set_render_priority(RID p_material, int priority);
+
void _update_material(Material *material);
void update_dirty_materials();
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index d793ea446d..bdd54543d2 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -608,6 +608,9 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} else {
code = "return;";
}
+ } else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) {
+
+ code = "discard;";
}
} break;
@@ -748,11 +751,11 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss";
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy";
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
- actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread";
+ //actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread";
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
+ actions[VS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission";
actions[VS::SHADER_SPATIAL].renames["AO"] = "ao";
actions[VS::SHADER_SPATIAL].renames["EMISSION"] = "emission";
- actions[VS::SHADER_SPATIAL].renames["DISCARD"] = "_discard";
//actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord";
actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
@@ -780,6 +783,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n";
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n";
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
@@ -790,7 +794,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
- actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index f0dc14c35a..3bcfd24383 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -116,9 +116,12 @@ void main() {
#ifdef USE_TEXTURE_RECT
-
- uv_interp = src_rect.xy + abs(src_rect.zw) * vertex;
- highp vec4 outvec = vec4(dst_rect.xy + dst_rect.zw * mix(vertex,vec2(1.0,1.0)-vertex,lessThan(src_rect.zw,vec2(0.0,0.0))),0.0,1.0);
+ if (dst_rect.z < 0) { // Transpose is encoded as negative dst_rect.z
+ uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.yx;
+ } else {
+ uv_interp = src_rect.xy + abs(src_rect.zw) * vertex;
+ }
+ highp vec4 outvec = vec4(dst_rect.xy + abs(dst_rect.zw) * mix(vertex,vec2(1.0,1.0)-vertex,lessThan(src_rect.zw,vec2(0.0,0.0))),0.0,1.0);
#else
uv_interp = uv_attrib;
@@ -572,6 +575,18 @@ FRAGMENT_SHADER_CODE
#ifdef SHADOW_FILTER_PCF5
+ SHADOW_TEST(su+shadowpixel_size*2.0);
+ SHADOW_TEST(su+shadowpixel_size);
+ SHADOW_TEST(su);
+ SHADOW_TEST(su-shadowpixel_size);
+ SHADOW_TEST(su-shadowpixel_size*2.0);
+ shadow_attenuation/=5.0;
+
+#endif
+
+
+#ifdef SHADOW_FILTER_PCF7
+
SHADOW_TEST(su+shadowpixel_size*3.0);
SHADOW_TEST(su+shadowpixel_size*2.0);
SHADOW_TEST(su+shadowpixel_size);
@@ -579,7 +594,7 @@ FRAGMENT_SHADER_CODE
SHADOW_TEST(su-shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0);
SHADOW_TEST(su-shadowpixel_size*3.0);
- shadow_attenuation/=5.0;
+ shadow_attenuation/=7.0;
#endif
@@ -635,4 +650,3 @@ FRAGMENT_SHADER_CODE
frag_color = color;
}
-
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index c1504593cb..7c60a8ee97 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -887,7 +887,7 @@ float GTR1(float NdotH, float a)
-void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
+void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
@@ -900,10 +900,16 @@ LIGHT_SHADER_CODE
float dotNL = max(dot(N,L), 0.0 );
-#if defined(DIFFUSE_HALF_LAMBERT)
+#if defined(DIFFUSE_OREN_NAYAR)
+ vec3 light_amount;
+#else
+ float light_amount;
+#endif
+
- float hl = dot(N,L) * 0.5 + 0.5;
- diffuse += hl * light_color * diffuse_color;
+#if defined(DIFFUSE_LAMBERT_WRAP)
+ //energy conserving lambert wrap shader
+ light_amount = max(0.0,(dot(N,L) + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
#elif defined(DIFFUSE_OREN_NAYAR)
@@ -919,12 +925,12 @@ LIGHT_SHADER_CODE
vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33));
float B = 0.45 * sigma2 / (sigma2 + 0.09);
- diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
+ light_amount = max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
}
#elif defined(DIFFUSE_TOON)
- diffuse += smoothstep(-roughness,max(roughness,0.01),dot(N,L)) * light_color * diffuse_color;
+ light_amount = smoothstep(-roughness,max(roughness,0.01),dot(N,L));
#elif defined(DIFFUSE_BURLEY)
@@ -939,11 +945,17 @@ LIGHT_SHADER_CODE
float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NdotL, 5.0);
float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NdotV, 5.0);
- diffuse+= light_color * diffuse_color * lightScatter * viewScatter * energyFactor;
+ light_amount = lightScatter * viewScatter * energyFactor;
}
#else
//lambert
- diffuse += dotNL * light_color * diffuse_color;
+ light_amount = dotNL;
+#endif
+
+#if defined(TRANSMISSION_USED)
+ diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission);
+#else
+ diffuse += light_color * diffuse_color * light_amount;
#endif
@@ -1116,7 +1128,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
}
#endif
-void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -1170,11 +1182,11 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
-void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 transmission,float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -1204,7 +1216,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
@@ -1499,6 +1511,7 @@ void main() {
//lay out everything, whathever is unused is optimized away anyway
highp vec3 vertex = vertex_interp;
vec3 albedo = vec3(0.8,0.8,0.8);
+ vec3 transmission = vec3(0.0);
float metallic = 0.0;
float specular = 0.5;
vec3 emission = vec3(0.0,0.0,0.0);
@@ -1559,10 +1572,6 @@ void main() {
vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size;
#endif
-#if defined(ENABLE_DISCARD)
- bool discard_=false;
-#endif
-
#if defined (ENABLE_SSS)
float sss_strength=0.0;
#endif
@@ -1603,13 +1612,6 @@ FRAGMENT_SHADER_CODE
#endif
-#if defined(ENABLE_DISCARD)
- if (discard_) {
- //easy to eliminate dead code
- discard;
- }
-#endif
-
#ifdef ENABLE_CLIP_ALPHA
if (albedo.a<0.99) {
//used for doublepass and shadowmapping
@@ -1833,7 +1835,7 @@ FRAGMENT_SHADER_CODE
specular_light*=mix(vec3(1.0),light_attenuation,specular_light_interp.a);
#else
- light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
#endif
@@ -1871,11 +1873,11 @@ FRAGMENT_SHADER_CODE
#else
for(int i=0;i<omni_light_count;i++) {
- light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
+ light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
}
for(int i=0;i<spot_light_count;i++) {
- light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
+ light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
}
#endif //USE_VERTEX_LIGHTING
diff --git a/drivers/gles3/shaders/ssao_blur.glsl b/drivers/gles3/shaders/ssao_blur.glsl
index ce4154f50c..c7c978dc37 100644
--- a/drivers/gles3/shaders/ssao_blur.glsl
+++ b/drivers/gles3/shaders/ssao_blur.glsl
@@ -56,6 +56,8 @@ uniform ivec2 axis;
uniform float camera_z_far;
uniform float camera_z_near;
+uniform ivec2 screen_size;
+
void main() {
ivec2 ssC = ivec2(gl_FragCoord.xy);
@@ -83,6 +85,7 @@ void main() {
float totalWeight = BASE;
sum *= totalWeight;
+ ivec2 clamp_limit = screen_size - ivec2(1);
for (int r = -R; r <= R; ++r) {
// We already handled the zero case above. This loop should be unrolled and the static branch optimized out,
@@ -90,8 +93,8 @@ void main() {
if (r != 0) {
ivec2 ppos = ssC + axis * (r * SCALE);
- float value = texelFetch(source_ssao, ppos, 0).r;
- float temp_depth = texelFetch(source_depth, ssC, 0).r;
+ float value = texelFetch(source_ssao, clamp(ppos,ivec2(0),clamp_limit), 0).r;
+ float temp_depth = texelFetch(source_depth, clamp(ssC,ivec2(0),clamp_limit), 0).r;
temp_depth = temp_depth * 2.0 - 1.0;
temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near));
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index 46c9442ffc..246d4d7650 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -216,8 +216,8 @@ void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const
struct PNGReadStatus {
- int offset;
- int size;
+ uint32_t offset;
+ uint32_t size;
const unsigned char *image;
};
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index 356b1ad958..1798c84d85 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -33,6 +33,7 @@
#include <pulse/error.h>
+#include "os/os.h"
#include "project_settings.h"
Error AudioDriverPulseAudio::init() {
@@ -44,7 +45,7 @@ Error AudioDriverPulseAudio::init() {
samples_in = NULL;
samples_out = NULL;
- mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
+ mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
@@ -53,12 +54,17 @@ Error AudioDriverPulseAudio::init() {
spec.channels = channels;
spec.rate = mix_rate;
- int latency = GLOBAL_DEF("audio/output_latency", 25);
- buffer_size = closest_power_of_2(latency * mix_rate / 1000);
+ int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
+ buffer_size = buffer_frames * channels;
+
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ }
pa_buffer_attr attr;
- // set to appropriate buffer size from global settings
- attr.tlength = buffer_size;
+ // set to appropriate buffer length (in bytes) from global settings
+ attr.tlength = buffer_size * sizeof(int16_t);
// set them to be automatically chosen
attr.prebuf = (uint32_t)-1;
attr.maxlength = (uint32_t)-1;
@@ -80,8 +86,8 @@ Error AudioDriverPulseAudio::init() {
ERR_FAIL_COND_V(pulse == NULL, ERR_CANT_OPEN);
}
- samples_in = memnew_arr(int32_t, buffer_size * channels);
- samples_out = memnew_arr(int16_t, buffer_size * channels);
+ samples_in = memnew_arr(int32_t, buffer_size);
+ samples_out = memnew_arr(int16_t, buffer_size);
mutex = Mutex::create();
thread = Thread::create(AudioDriverPulseAudio::thread_func, this);
@@ -106,18 +112,18 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
while (!ad->exit_thread) {
if (!ad->active) {
- for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
+ for (unsigned int i = 0; i < ad->buffer_size; i++) {
ad->samples_out[i] = 0;
}
} else {
ad->lock();
- ad->audio_server_process(ad->buffer_size, ad->samples_in);
+ ad->audio_server_process(ad->buffer_frames, ad->samples_in);
ad->unlock();
- for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
+ for (unsigned int i = 0; i < ad->buffer_size; i++) {
ad->samples_out[i] = ad->samples_in[i] >> 16;
}
}
@@ -125,7 +131,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
// pa_simple_write always consumes the entire buffer
int error_code;
- int byte_size = ad->buffer_size * sizeof(int16_t) * ad->channels;
+ int byte_size = ad->buffer_size * sizeof(int16_t);
if (pa_simple_write(ad->pulse, ad->samples_out, byte_size, &error_code) < 0) {
// can't recover here
fprintf(stderr, "PulseAudio failed and can't recover: %s\n", pa_strerror(error_code));
@@ -175,13 +181,20 @@ void AudioDriverPulseAudio::finish() {
exit_thread = true;
Thread::wait_to_finish(thread);
- if (pulse)
+ if (pulse) {
pa_simple_free(pulse);
+ pulse = NULL;
+ }
if (samples_in) {
memdelete_arr(samples_in);
+ samples_in = NULL;
+ }
+
+ if (samples_out) {
memdelete_arr(samples_out);
- };
+ samples_out = NULL;
+ }
memdelete(thread);
if (mutex) {
@@ -194,10 +207,15 @@ void AudioDriverPulseAudio::finish() {
AudioDriverPulseAudio::AudioDriverPulseAudio() {
+ samples_in = NULL;
+ samples_out = NULL;
mutex = NULL;
thread = NULL;
pulse = NULL;
latency = 0;
+ buffer_frames = 0;
+ buffer_size = 0;
+ channels = 0;
}
AudioDriverPulseAudio::~AudioDriverPulseAudio() {
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index 2f56726617..9ae0b7e50c 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -51,6 +51,7 @@ class AudioDriverPulseAudio : public AudioDriver {
unsigned int mix_rate;
SpeakerMode speaker_mode;
+ unsigned int buffer_frames;
unsigned int buffer_size;
int channels;
diff --git a/drivers/rtaudio/audio_driver_rtaudio.cpp b/drivers/rtaudio/audio_driver_rtaudio.cpp
index 7de3ff192e..ae5fdd28b6 100644
--- a/drivers/rtaudio/audio_driver_rtaudio.cpp
+++ b/drivers/rtaudio/audio_driver_rtaudio.cpp
@@ -107,14 +107,13 @@ Error AudioDriverRtAudio::init() {
options.numberOfBuffers = 4;
parameters.firstChannel = 0;
- mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
+ mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
- int latency = GLOBAL_DEF("audio/output_latency", 25);
- // calculate desired buffer_size
- unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000);
+ int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ unsigned int buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
if (OS::get_singleton()->is_stdout_verbose()) {
- print_line("audio buffer size: " + itos(buffer_size));
+ print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
}
short int tries = 2;
@@ -127,7 +126,7 @@ Error AudioDriverRtAudio::init() {
};
try {
- dac->openStream(&parameters, NULL, RTAUDIO_SINT32, mix_rate, &buffer_size, &callback, this, &options);
+ dac->openStream(&parameters, NULL, RTAUDIO_SINT32, mix_rate, &buffer_frames, &callback, this, &options);
active = true;
break;
@@ -199,7 +198,7 @@ AudioDriverRtAudio::AudioDriverRtAudio() {
active = false;
mutex = NULL;
dac = NULL;
- mix_rate = 44100;
+ mix_rate = DEFAULT_MIX_RATE;
speaker_mode = SPEAKER_MODE_STEREO;
}
diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp
index b743990b92..61d2737555 100644
--- a/drivers/unix/packet_peer_udp_posix.cpp
+++ b/drivers/unix/packet_peer_udp_posix.cpp
@@ -73,8 +73,8 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer, int &r_buffer_siz
if (queue_count == 0)
return ERR_UNAVAILABLE;
- uint32_t size;
- uint8_t type;
+ uint32_t size = 0;
+ uint8_t type = IP::TYPE_NONE;
rb.read(&type, 1, true);
if (type == IP::TYPE_IPV4) {
uint8_t ip[4];
diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp
index f3f9ab82f1..5062a74b63 100644
--- a/drivers/unix/tcp_server_posix.cpp
+++ b/drivers/unix/tcp_server_posix.cpp
@@ -165,7 +165,7 @@ Ref<StreamPeerTCP> TCPServerPosix::take_connection() {
Ref<StreamPeerTCPPosix> conn = memnew(StreamPeerTCPPosix);
IP_Address ip;
- int port;
+ int port = 0;
_set_ip_addr_port(ip, port, &their_addr);
conn->set_socket(fd, ip, port, sock_type);
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 6e01b5f524..29d1e5deed 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* audio_driver_wasapi.cpp */
+/* audio_driver_wasapi.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -65,6 +65,18 @@ Error AudioDriverWASAPI::init_device() {
format_tag = pwfex->wFormatTag;
bits_per_sample = pwfex->wBitsPerSample;
+ switch (channels) {
+ case 2: // Stereo
+ case 6: // Surround 5.1
+ case 8: // Surround 7.1
+ break;
+
+ default:
+ ERR_PRINT("WASAPI: Unsupported number of channels");
+ ERR_FAIL_V(ERR_CANT_OPEN);
+ break;
+ }
+
if (format_tag == WAVE_FORMAT_EXTENSIBLE) {
WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE *)pwfex;
@@ -83,13 +95,6 @@ Error AudioDriverWASAPI::init_device() {
}
}
- int latency = GLOBAL_DEF("audio/output_latency", 25);
- buffer_size = closest_power_of_2(latency * mix_rate / 1000);
-
- if (OS::get_singleton()->is_stdout_verbose()) {
- print_line("audio buffer size: " + itos(buffer_size));
- }
-
hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 0, 0, pwfex, NULL);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
@@ -102,11 +107,20 @@ Error AudioDriverWASAPI::init_device() {
hr = audio_client->GetService(IID_IAudioRenderClient, (void **)&render_client);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ UINT32 max_frames;
hr = audio_client->GetBufferSize(&max_frames);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ // Due to WASAPI Shared Mode we have no control of the buffer size
+ buffer_frames = max_frames;
+
+ // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
+ buffer_size = buffer_frames * channels;
samples_in.resize(buffer_size);
- buffer_frames = buffer_size / channels;
+
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ }
return OK;
}
@@ -200,7 +214,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
HRESULT hr = ad->audio_client->GetCurrentPadding(&cur_frames);
if (hr == S_OK) {
// Check how much frames are available on the WASAPI buffer
- UINT32 avail_frames = ad->max_frames - cur_frames;
+ UINT32 avail_frames = ad->buffer_frames - cur_frames;
UINT32 write_frames = avail_frames > left_frames ? left_frames : avail_frames;
BYTE *buffer = NULL;
@@ -332,7 +346,6 @@ AudioDriverWASAPI::AudioDriverWASAPI() {
mutex = NULL;
thread = NULL;
- max_frames = 0;
format_tag = 0;
bits_per_sample = 0;
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index b91751f87e..fab8ab3250 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* audio_driver_wasapi.h */
+/* audio_driver_wasapi.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -48,7 +48,6 @@ class AudioDriverWASAPI : public AudioDriver {
Mutex *mutex;
Thread *thread;
- UINT32 max_frames;
WORD format_tag;
WORD bits_per_sample;
diff --git a/editor/SCsub b/editor/SCsub
index 172447147c..0e690cf465 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -155,31 +155,71 @@ def make_authors_header(target, source, env):
g.write("#define _EDITOR_AUTHORS_H\n")
current_section = ""
- name_count = -1
+ reading = False
def close_section():
g.write("\t0\n")
g.write("};\n")
- g.write("#define " + current_section.upper() + "_COUNT " + str(name_count) + "\n")
for line in f:
- if name_count >= 0:
+ if reading:
if line.startswith(" "):
g.write("\t\"" + line.strip() + "\",\n")
- name_count += 1
continue
if line.startswith("## "):
- if name_count >= 0:
+ if reading:
close_section()
- name_count = -1
+ reading = False
for i in range(len(sections)):
if line.strip().endswith(sections[i]):
current_section = sections_id[i]
- name_count = 0
+ reading = True
g.write("static const char *" + current_section + "[] = {\n")
break
- if name_count >= 0:
+ if reading:
+ close_section()
+
+ g.write("#endif\n")
+
+def make_donors_header(target, source, env):
+
+ sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"]
+ sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"]
+
+ src = source[0].srcnode().abspath
+ dst = target[0].srcnode().abspath
+ f = open_utf8(src, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_DONORS_H\n")
+ g.write("#define _EDITOR_DONORS_H\n")
+
+ current_section = ""
+ reading = False
+
+ def close_section():
+ g.write("\t0\n")
+ g.write("};\n")
+
+ for line in f:
+ if reading >= 0:
+ if line.startswith(" "):
+ g.write("\t\"" + line.strip() + "\",\n")
+ continue
+ if line.startswith("## "):
+ if reading:
+ close_section()
+ reading = False
+ for i in range(len(sections)):
+ if line.strip().endswith(sections[i]):
+ current_section = sections_id[i]
+ reading = True
+ g.write("static const char *" + current_section + "[] = {\n")
+ break
+
+ if reading:
close_section()
g.write("#endif\n")
@@ -393,6 +433,10 @@ if (env["tools"] == "yes"):
env.Depends('#editor/authors.gen.h', "../AUTHORS.md")
env.Command('#editor/authors.gen.h', "../AUTHORS.md", make_authors_header)
+ # Donors
+ env.Depends('#editor/donors.gen.h', "../DONORS.md")
+ env.Command('#editor/donors.gen.h', "../DONORS.md", make_donors_header)
+
# License
env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"])
env.Command('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], make_license_header)
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 305e2e9159..8c153d2745 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -30,6 +30,7 @@
#include "code_editor.h"
#include "editor/editor_scale.h"
+#include "editor_node.h"
#include "editor_settings.h"
#include "os/keyboard.h"
#include "scene/gui/margin_container.h"
@@ -91,6 +92,13 @@ void FindReplaceBar::_notification(int p_what) {
} else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
set_process_unhandled_input(is_visible_in_tree());
+ } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+
+ find_prev->set_icon(get_icon("MoveUp", "EditorIcons"));
+ find_next->set_icon(get_icon("MoveDown", "EditorIcons"));
+ hide_button->set_normal_texture(get_icon("Close", "EditorIcons"));
+ hide_button->set_hover_texture(get_icon("CloseHover", "EditorIcons"));
+ hide_button->set_pressed_texture(get_icon("Close", "EditorIcons"));
}
}
@@ -544,9 +552,7 @@ FindReplaceBar::FindReplaceBar() {
error_label = memnew(Label);
search_options->add_child(error_label);
- error_label->add_color_override("font_color", Color(1, 1, 0, 1));
- error_label->add_color_override("font_color_shadow", Color(0, 0, 0, 1));
- error_label->add_constant_override("shadow_as_outline", 1);
+ error_label->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
search_options->add_spacer();
@@ -875,7 +881,6 @@ FindReplaceDialog::FindReplaceDialog() {
search_text = memnew(LineEdit);
vb->add_margin_child(TTR("Search"), search_text);
search_text->connect("text_entered", this, "_search_text_entered");
- //search_text->set_self_opacity(0.7);
replace_label = memnew(Label);
replace_label->set_text(TTR("Replace By"));
@@ -887,7 +892,7 @@ FindReplaceDialog::FindReplaceDialog() {
replace_text->set_anchor(MARGIN_RIGHT, ANCHOR_END);
replace_text->set_begin(Point2(15, 132));
replace_text->set_end(Point2(-15, 135));
- //replace_text->set_self_opacity(0.7);
+
replace_mc->add_child(replace_text);
replace_text->connect("text_entered", this, "_replace_text_entered");
@@ -944,9 +949,7 @@ FindReplaceDialog::FindReplaceDialog() {
error_label = memnew(Label);
error_label->set_align(Label::ALIGN_CENTER);
- error_label->add_color_override("font_color", Color(1, 0.4, 0.3));
- error_label->add_color_override("font_color_shadow", Color(0, 0, 0, 0.2));
- error_label->add_constant_override("shadow_as_outline", 1);
+ error_label->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
vb->add_child(error_label);
@@ -1076,6 +1079,7 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
text_editor->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type"));
text_editor->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size"));
+ text_editor->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent"));
text_editor->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs"));
text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers"));
text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_numbers_zero_padded"));
@@ -1220,7 +1224,7 @@ CodeTextEditor::CodeTextEditor() {
status_bar->add_child(error);
error->set_clip_text(true); //do not change, or else very long errors can push the whole container to the right
error->set_valign(Label::VALIGN_CENTER);
- error->add_color_override("font_color", Color(1, 0.7, 0.6, 0.9));
+ error->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
error->set_h_size_flags(SIZE_EXPAND_FILL); //required for it to display, given now it's clipping contents, do not touch
Label *line_txt = memnew(Label);
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index 208341add3..6848c43b68 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -163,6 +163,43 @@ void DocData::remove_from(const DocData &p_data) {
}
}
+static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) {
+
+ if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ p_method.return_enum = p_retinfo.class_name;
+ p_method.return_type = "int";
+ } else if (p_retinfo.class_name != StringName()) {
+ p_method.return_type = p_retinfo.class_name;
+ } else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ p_method.return_type = p_retinfo.hint_string;
+ } else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
+ p_method.return_type = "Variant";
+ } else if (p_retinfo.type == Variant::NIL) {
+ p_method.return_type = "void";
+ } else {
+ p_method.return_type = Variant::get_type_name(p_retinfo.type);
+ }
+}
+
+static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) {
+
+ p_argument.name = p_arginfo.name;
+
+ if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ p_argument.enumeration = p_arginfo.class_name;
+ p_argument.type = "int";
+ } else if (p_arginfo.class_name != StringName()) {
+ p_argument.type = p_arginfo.class_name;
+ } else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ p_argument.type = p_arginfo.hint_string;
+ } else if (p_arginfo.type == Variant::NIL) {
+ // Parameters cannot be void, so PROPERTY_USAGE_NIL_IS_VARIANT is not necessary
+ p_argument.type = "Variant";
+ } else {
+ p_argument.type = Variant::get_type_name(p_arginfo.type);
+ }
+}
+
void DocData::generate(bool p_basic_types) {
List<StringName> classes;
@@ -263,51 +300,17 @@ void DocData::generate(bool p_basic_types) {
for (int i = -1; i < E->get().arguments.size(); i++) {
if (i == -1) {
-
#ifdef DEBUG_METHODS_ENABLED
-
- PropertyInfo retinfo = E->get().return_val;
-
- if (retinfo.type == Variant::INT && retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
- method.return_enum = retinfo.class_name;
- method.return_type = "int";
- } else if (retinfo.class_name != StringName()) {
- method.return_type = retinfo.class_name;
- } else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
-
- method.return_type = retinfo.hint_string;
- } else if (retinfo.type == Variant::NIL && retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
-
- method.return_type = "Variant";
- } else if (retinfo.type == Variant::NIL) {
- method.return_type = "void";
- } else {
- method.return_type = Variant::get_type_name(retinfo.type);
- }
+ return_doc_from_retinfo(method, E->get().return_val);
#endif
-
} else {
- ArgumentDoc argument;
+ const PropertyInfo &arginfo = E->get().arguments[i];
- PropertyInfo arginfo = E->get().arguments[i];
-
- if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
- argument.enumeration = arginfo.class_name;
- argument.type = "int";
- } else if (arginfo.class_name != StringName()) {
- argument.type = arginfo.class_name;
- } else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
-
- argument.type = arginfo.hint_string;
- } else if (arginfo.type == Variant::NIL && arginfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
+ ArgumentDoc argument;
- argument.type = "Variant";
- } else {
- argument.type = Variant::get_type_name(arginfo.type);
- }
+ argument_doc_from_arginfo(argument, arginfo);
- argument.name = E->get().arguments[i].name;
int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size());
if (darg_idx >= 0) {
@@ -464,26 +467,26 @@ void DocData::generate(bool p_basic_types) {
for (int i = 0; i < mi.arguments.size(); i++) {
- ArgumentDoc arg;
- PropertyInfo pi = mi.arguments[i];
+ PropertyInfo arginfo = mi.arguments[i];
- arg.name = pi.name;
- //print_line("arg name: "+arg.name);
- if (pi.type == Variant::NIL)
- arg.type = "var";
+ ArgumentDoc ad;
+ ad.name = arginfo.name;
+
+ if (arginfo.type == Variant::NIL)
+ ad.type = "var";
else
- arg.type = Variant::get_type_name(pi.type);
+ ad.type = Variant::get_type_name(arginfo.type);
+
int defarg = mi.default_arguments.size() - mi.arguments.size() + i;
if (defarg >= 0)
- arg.default_value = mi.default_arguments[defarg];
+ ad.default_value = mi.default_arguments[defarg];
- method.arguments.push_back(arg);
+ method.arguments.push_back(ad);
}
if (mi.return_val.type == Variant::NIL) {
if (mi.return_val.name != "")
method.return_type = "var";
-
} else {
method.return_type = Variant::get_type_name(mi.return_val.type);
}
@@ -572,26 +575,19 @@ void DocData::generate(bool p_basic_types) {
MethodInfo &mi = E->get();
MethodDoc md;
md.name = mi.name;
- if (mi.return_val.name != "")
- md.return_type = mi.return_val.name;
- else if (mi.name.find(":") != -1) {
- md.return_type = mi.name.get_slice(":", 1);
- md.name = mi.name.get_slice(":", 0);
- } else
- md.return_type = Variant::get_type_name(mi.return_val.type);
- for (int i = 0; i < mi.arguments.size(); i++) {
-
- PropertyInfo &pi = mi.arguments[i];
+ if (mi.flags & METHOD_FLAG_VARARG) {
+ if (md.qualifiers != "")
+ md.qualifiers += " ";
+ md.qualifiers += "vararg";
+ }
- ArgumentDoc ad;
- ad.name = pi.name;
+ return_doc_from_retinfo(md, mi.return_val);
- if (pi.type == Variant::NIL)
- ad.type = "Variant";
- else
- ad.type = Variant::get_type_name(pi.type);
+ for (int i = 0; i < mi.arguments.size(); i++) {
+ ArgumentDoc ad;
+ argument_doc_from_arginfo(ad, mi.arguments[i]);
md.arguments.push_back(ad);
}
@@ -638,6 +634,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
method.return_type = parser->get_attribute_value("type");
+ if (parser->has_attribute("enum")) {
+ method.return_enum = parser->get_attribute_value("enum");
+ }
} else if (name == "argument") {
DocData::ArgumentDoc argument;
@@ -920,7 +919,11 @@ Error DocData::save(const String &p_path) {
if (m.return_type != "") {
- _write_string(f, 3, "<return type=\"" + m.return_type + "\">");
+ String enum_text;
+ if (m.return_enum != String()) {
+ enum_text = " enum=\"" + m.return_enum + "\"";
+ }
+ _write_string(f, 3, "<return type=\"" + m.return_type + "\"" + enum_text + ">");
_write_string(f, 3, "</return>");
}
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 8bd7bfb4bd..a48e6c9057 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -30,6 +30,7 @@
#include "editor_about.h"
#include "authors.gen.h"
+#include "donors.gen.h"
#include "license.gen.h"
#include "version.h"
#include "version_hash.gen.h"
@@ -51,6 +52,47 @@ TextureRect *EditorAbout::get_logo() const {
return _logo;
}
+ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]) {
+
+ ScrollContainer *sc = memnew(ScrollContainer);
+ sc->set_name(p_name);
+ sc->set_v_size_flags(Control::SIZE_EXPAND);
+
+ VBoxContainer *vbc = memnew(VBoxContainer);
+ vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ sc->add_child(vbc);
+
+ for (int i = 0; i < p_sections.size(); i++) {
+
+ const char **names_ptr = p_src[i];
+ if (*names_ptr) {
+
+ Label *lbl = memnew(Label);
+ lbl->set_text(p_sections[i]);
+ vbc->add_child(lbl);
+
+ ItemList *il = memnew(ItemList);
+ il->set_max_columns(16);
+ il->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ il->set_same_column_width(true);
+ il->set_auto_height(true);
+ while (*names_ptr) {
+ il->add_item(String::utf8(*names_ptr++), NULL, false);
+ }
+ vbc->add_child(il);
+ if (il->get_item_count() == 2) {
+ il->set_fixed_column_width(200 * EDSCALE);
+ }
+
+ HSeparator *hs = memnew(HSeparator);
+ hs->set_modulate(Color(0, 0, 0, 0));
+ vbc->add_child(hs);
+ }
+ }
+
+ return sc;
+}
+
EditorAbout::EditorAbout() {
set_title(TTR("Thanks from the Godot community!"));
@@ -84,43 +126,29 @@ EditorAbout::EditorAbout() {
tc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
vbc->add_child(tc);
- ScrollContainer *dev_base = memnew(ScrollContainer);
- dev_base->set_name(TTR("Authors"));
- dev_base->set_v_size_flags(Control::SIZE_EXPAND);
- tc->add_child(dev_base);
-
- VBoxContainer *dev_vbc = memnew(VBoxContainer);
- dev_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- dev_base->add_child(dev_vbc);
+ // Authors
List<String> dev_sections;
dev_sections.push_back(TTR("Project Founders"));
dev_sections.push_back(TTR("Lead Developer"));
dev_sections.push_back(TTR("Project Manager"));
dev_sections.push_back(TTR("Developers"));
-
const char **dev_src[] = { dev_founders, dev_lead, dev_manager, dev_names };
+ tc->add_child(_populate_list(TTR("Authors"), dev_sections, dev_src));
- for (int i = 0; i < dev_sections.size(); i++) {
-
- Label *lbl = memnew(Label);
- lbl->set_text(dev_sections[i]);
- dev_vbc->add_child(lbl);
-
- ItemList *il = memnew(ItemList);
- il->set_max_columns(16);
- il->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- il->set_fixed_column_width(230 * EDSCALE);
- il->set_auto_height(true);
- const char **dev_names_ptr = dev_src[i];
- while (*dev_names_ptr)
- il->add_item(String::utf8(*dev_names_ptr++), NULL, false);
- dev_vbc->add_child(il);
-
- HSeparator *hs = memnew(HSeparator);
- hs->set_modulate(Color(0, 0, 0, 0));
- dev_vbc->add_child(hs);
- }
+ // Donors
+
+ List<String> donor_sections;
+ donor_sections.push_back(TTR("Platinum Sponsors"));
+ donor_sections.push_back(TTR("Gold Sponsors"));
+ donor_sections.push_back(TTR("Mini Sponsors"));
+ donor_sections.push_back(TTR("Gold Donors"));
+ donor_sections.push_back(TTR("Silver Donors"));
+ donor_sections.push_back(TTR("Bronze Donors"));
+ const char **donor_src[] = { donor_s_plat, donor_s_gold, donor_s_mini, donor_gold, donor_silver, donor_bronze };
+ tc->add_child(_populate_list(TTR("Donors"), donor_sections, donor_src));
+
+ // License
TextEdit *license = memnew(TextEdit);
license->set_name(TTR("License"));
@@ -131,6 +159,8 @@ EditorAbout::EditorAbout() {
license->set_text(String::utf8(about_license));
tc->add_child(license);
+ // Thirdparty License
+
VBoxContainer *license_thirdparty = memnew(VBoxContainer);
license_thirdparty->set_name(TTR("Thirdparty License"));
license_thirdparty->set_h_size_flags(Control::SIZE_EXPAND_FILL);
diff --git a/editor/editor_about.h b/editor/editor_about.h
index d7047c03a3..d455b1f074 100644
--- a/editor/editor_about.h
+++ b/editor/editor_about.h
@@ -52,6 +52,7 @@ class EditorAbout : public AcceptDialog {
private:
void _license_tree_selected();
+ ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]);
Tree *_tpl_tree;
TextEdit *_tpl_text;
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index b3eb3e23a9..6937f74316 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -70,11 +70,14 @@ void EditorAudioBus::_notification(int p_what) {
float real_peak[2] = { -100, -100 };
bool activity_found = false;
- int cc;
+ int cc = 0;
switch (AudioServer::get_singleton()->get_speaker_mode()) {
case AudioServer::SPEAKER_MODE_STEREO: cc = 1; break;
case AudioServer::SPEAKER_SURROUND_51: cc = 4; break;
case AudioServer::SPEAKER_SURROUND_71: cc = 5; break;
+ default:
+ ERR_PRINT("Unknown speaker_mode");
+ break;
}
for (int i = 0; i < cc; i++) {
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index cb74a7b852..2cb5340b8b 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -141,7 +141,7 @@ ObjectID EditorHistory::get_history_obj(int p_obj) const {
return history[p_obj].path[history[p_obj].level].object;
}
-bool EditorHistory::is_at_begining() const {
+bool EditorHistory::is_at_beginning() const {
return current <= 0;
}
bool EditorHistory::is_at_end() const {
diff --git a/editor/editor_data.h b/editor/editor_data.h
index cbba4d60ad..33a4091a65 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -74,7 +74,7 @@ class EditorHistory {
void _add_object(ObjectID p_object, const String &p_property, int p_level_change);
public:
- bool is_at_begining() const;
+ bool is_at_beginning() const;
bool is_at_end() const;
void add_object(ObjectID p_object);
diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp
index 1b213501aa..cfb3abfd1d 100644
--- a/editor/editor_dir_dialog.cpp
+++ b/editor/editor_dir_dialog.cpp
@@ -31,50 +31,40 @@
#include "editor/editor_file_system.h"
#include "editor/editor_settings.h"
+#include "editor_scale.h"
#include "os/keyboard.h"
#include "os/os.h"
-
-void EditorDirDialog::_update_dir(TreeItem *p_item) {
+void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) {
updating = true;
- p_item->clear_children();
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- String cdir = p_item->get_metadata(0);
-
- da->change_dir(cdir);
- da->list_dir_begin();
- String p = da->get_next();
- List<String> dirs;
- bool ishidden;
- bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files");
+ String path = p_dir->get_path();
- while (p != "") {
+ p_item->set_metadata(0, p_dir->get_path());
+ p_item->set_icon(0, get_icon("Folder", "EditorIcons"));
- ishidden = da->current_is_hidden();
+ if (!p_item->get_parent()) {
+ p_item->set_text(0, "res://");
+ } else {
- if (show_hidden || !ishidden) {
- if (da->current_is_dir() && !p.begins_with(".")) {
- dirs.push_back(p);
- }
+ if (!opened_paths.has(path) && (p_select_path == String() || !p_select_path.begins_with(path))) {
+ p_item->set_collapsed(true);
}
- p = da->get_next();
+
+ p_item->set_text(0, p_dir->get_name());
}
- dirs.sort();
+ //this should be handled by EditorFileSystem already
+ //bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files");
+ updating = false;
+ for (int i = 0; i < p_dir->get_subdir_count(); i++) {
- for (List<String>::Element *E = dirs.front(); E; E = E->next()) {
TreeItem *ti = tree->create_item(p_item);
- ti->set_text(0, E->get());
- ti->set_icon(0, get_icon("Folder", "EditorIcons"));
- ti->set_collapsed(true);
+ _update_dir(ti, p_dir->get_subdir(i));
}
-
- memdelete(da);
- updating = false;
}
-void EditorDirDialog::reload() {
+void EditorDirDialog::reload(const String &p_with_path) {
if (!is_visible_in_tree()) {
must_reload = true;
@@ -83,10 +73,7 @@ void EditorDirDialog::reload() {
tree->clear();
TreeItem *root = tree->create_item();
- root->set_metadata(0, "res://");
- root->set_icon(0, get_icon("Folder", "EditorIcons"));
- root->set_text(0, "/");
- _update_dir(root);
+ _update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_with_path);
_item_collapsed(root);
must_reload = false;
}
@@ -94,6 +81,7 @@ void EditorDirDialog::reload() {
void EditorDirDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
+ EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "reload");
reload();
if (!tree->is_connected("item_collapsed", this, "_item_collapsed")) {
@@ -105,6 +93,10 @@ void EditorDirDialog::_notification(int p_what) {
}
}
+ if (p_what == NOTIFICATION_EXIT_TREE) {
+ EditorFileSystem::get_singleton()->disconnect("filesystem_changed", this, "reload");
+ }
+
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
if (must_reload && is_visible_in_tree()) {
reload();
@@ -116,57 +108,13 @@ void EditorDirDialog::_item_collapsed(Object *p_item) {
TreeItem *item = Object::cast_to<TreeItem>(p_item);
- if (updating || item->is_collapsed())
+ if (updating)
return;
- TreeItem *ci = item->get_children();
- while (ci) {
-
- String p = ci->get_metadata(0);
- if (p == "") {
- String pp = item->get_metadata(0);
- ci->set_metadata(0, pp.plus_file(ci->get_text(0)));
- _update_dir(ci);
- }
- ci = ci->get_next();
- }
-}
-
-void EditorDirDialog::set_current_path(const String &p_path) {
-
- reload();
- String p = p_path;
- if (p.begins_with("res://"))
- p = p.replace_first("res://", "");
-
- Vector<String> dirs = p.split("/", false);
-
- TreeItem *r = tree->get_root();
- for (int i = 0; i < dirs.size(); i++) {
-
- String d = dirs[i];
- TreeItem *p = r->get_children();
- while (p) {
-
- if (p->get_text(0) == d)
- break;
- p = p->get_next();
- }
-
- ERR_FAIL_COND(!p);
- String pp = p->get_metadata(0);
- if (pp == "") {
- p->set_metadata(0, String(r->get_metadata(0)).plus_file(d));
- _update_dir(p);
- }
- updating = true;
- p->set_collapsed(false);
- updating = false;
- _item_collapsed(p);
- r = p;
- }
-
- r->select(0);
+ if (item->is_collapsed())
+ opened_paths.erase(item->get_metadata(0));
+ else
+ opened_paths.insert(item->get_metadata(0));
}
void EditorDirDialog::ok_pressed() {
@@ -201,14 +149,16 @@ void EditorDirDialog::_make_dir_confirm() {
String dir = ti->get_metadata(0);
- DirAccess *d = DirAccess::open(dir);
+ DirAccessRef d = DirAccess::open(dir);
ERR_FAIL_COND(!d);
Error err = d->make_dir(makedirname->get_text());
if (err != OK) {
- mkdirerr->popup_centered_minsize(Size2(250, 80));
+ mkdirerr->popup_centered_minsize(Size2(250, 80) * EDSCALE);
} else {
- set_current_path(dir.plus_file(makedirname->get_text()));
+ opened_paths.insert(dir);
+ //reload(dir.plus_file(makedirname->get_text()));
+ EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes
}
makedirname->set_text(""); // reset label
}
@@ -218,7 +168,7 @@ void EditorDirDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_item_collapsed"), &EditorDirDialog::_item_collapsed);
ClassDB::bind_method(D_METHOD("_make_dir"), &EditorDirDialog::_make_dir);
ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &EditorDirDialog::_make_dir_confirm);
- ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload);
+ ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload, DEFVAL(""));
ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir")));
}
diff --git a/editor/editor_dir_dialog.h b/editor/editor_dir_dialog.h
index b8347f75fb..8aa685947b 100644
--- a/editor/editor_dir_dialog.h
+++ b/editor/editor_dir_dialog.h
@@ -30,6 +30,7 @@
#ifndef EDITOR_DIR_DIALOG_H
#define EDITOR_DIR_DIALOG_H
+#include "editor/editor_file_system.h"
#include "os/dir_access.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
@@ -42,12 +43,13 @@ class EditorDirDialog : public ConfirmationDialog {
AcceptDialog *mkdirerr;
Button *makedir;
+ Set<String> opened_paths;
Tree *tree;
bool updating;
void _item_collapsed(Object *p_item);
- void _update_dir(TreeItem *p_item);
+ void _update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path = String());
void _make_dir();
void _make_dir_confirm();
@@ -61,8 +63,7 @@ protected:
static void _bind_methods();
public:
- void set_current_path(const String &p_path);
- void reload();
+ void reload(const String &p_path = "");
EditorDirDialog();
};
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index e761dce8ab..915fb7e5db 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* editor_import_export.cpp */
+/* editor_export.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/editor/editor_export.h b/editor/editor_export.h
index feff9678af..3b99c68c85 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* editor_import_export.h */
+/* editor_export.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index ab994dbe75..abcdc0b64c 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -53,6 +53,7 @@ void EditorFileDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
+ //_update_icons
mode_thumbnails->set_icon(get_icon("FileThumbnail", "EditorIcons"));
mode_list->set_icon(get_icon("FileList", "EditorIcons"));
dir_prev->set_icon(get_icon("ArrowLeft", "EditorIcons"));
@@ -92,6 +93,23 @@ void EditorFileDialog::_notification(int p_what) {
if (show_hidden_files != show_hidden)
set_show_hidden_files(show_hidden);
set_display_mode((DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int());
+
+ //_update_icons
+ mode_thumbnails->set_icon(get_icon("FileThumbnail", "EditorIcons"));
+ mode_list->set_icon(get_icon("FileList", "EditorIcons"));
+ dir_prev->set_icon(get_icon("ArrowLeft", "EditorIcons"));
+ dir_next->set_icon(get_icon("ArrowRight", "EditorIcons"));
+ dir_up->set_icon(get_icon("ArrowUp", "EditorIcons"));
+ refresh->set_icon(get_icon("Reload", "EditorIcons"));
+ favorite->set_icon(get_icon("Favorites", "EditorIcons"));
+
+ fav_up->set_icon(get_icon("MoveUp", "EditorIcons"));
+ fav_down->set_icon(get_icon("MoveDown", "EditorIcons"));
+ fav_rm->set_icon(get_icon("RemoveSmall", "EditorIcons"));
+
+ Theme::get_default()->clear_icon("ResizedFile", "EditorIcons");
+ Theme::get_default()->clear_icon("ResizedFolder", "EditorIcons");
+ update_file_list();
}
}
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 9d110c7136..6e12a8fd02 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -118,6 +118,12 @@ Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const {
return files[p_idx]->deps;
}
+bool EditorFileSystemDirectory::get_file_import_is_valid(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx, files.size(), false);
+ return files[p_idx]->import_valid;
+}
+
StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, files.size(), "");
@@ -142,6 +148,7 @@ void EditorFileSystemDirectory::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_file", "idx"), &EditorFileSystemDirectory::get_file);
ClassDB::bind_method(D_METHOD("get_file_path", "idx"), &EditorFileSystemDirectory::get_file_path);
ClassDB::bind_method(D_METHOD("get_file_type", "idx"), &EditorFileSystemDirectory::get_file_type);
+ ClassDB::bind_method(D_METHOD("get_file_import_is_valid", "idx"), &EditorFileSystemDirectory::get_file_import_is_valid);
ClassDB::bind_method(D_METHOD("get_name"), &EditorFileSystemDirectory::get_name);
ClassDB::bind_method(D_METHOD("get_path"), &EditorFileSystemDirectory::get_path);
ClassDB::bind_method(D_METHOD("get_parent"), &EditorFileSystemDirectory::get_parent);
@@ -181,7 +188,7 @@ void EditorFileSystem::_scan_filesystem() {
String project = ProjectSettings::get_singleton()->get_resource_path();
- String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2");
+ String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache3");
FileAccess *f = FileAccess::open(fscache, FileAccess::READ);
if (f) {
@@ -201,7 +208,7 @@ void EditorFileSystem::_scan_filesystem() {
} else {
Vector<String> split = l.split("::");
- ERR_CONTINUE(split.size() != 5);
+ ERR_CONTINUE(split.size() != 6);
String name = split[0];
String file;
@@ -212,8 +219,9 @@ void EditorFileSystem::_scan_filesystem() {
fc.type = split[1];
fc.modification_time = split[2].to_int64();
fc.import_modification_time = split[3].to_int64();
+ fc.import_valid = split[4].to_int64() != 0;
- String deps = split[4].strip_edges();
+ String deps = split[5].strip_edges();
if (deps.length()) {
Vector<String> dp = deps.split("<>");
for (int i = 0; i < dp.size(); i++) {
@@ -230,7 +238,7 @@ void EditorFileSystem::_scan_filesystem() {
memdelete(f);
}
- String update_cache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update2");
+ String update_cache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update3");
print_line("try to see fs update2");
if (FileAccess::exists(update_cache)) {
@@ -282,7 +290,7 @@ void EditorFileSystem::_scan_filesystem() {
}
void EditorFileSystem::_save_filesystem_cache() {
- String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2");
+ String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache3");
FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE);
_save_filesystem_cache(filesystem, f);
@@ -622,6 +630,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
fi->deps = fc->deps;
fi->modified_time = fc->modification_time;
fi->import_modified_time = fc->import_modification_time;
+ fi->import_valid = fc->import_valid;
if (fc->type == String()) {
fi->type = ResourceLoader::get_resource_type(path);
//there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?)
@@ -648,6 +657,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
print_line("import extension tried resource type for " + path + " and its " + fi->type);
fi->modified_time = 0;
fi->import_modified_time = 0;
+ fi->import_valid = ResourceLoader::is_import_valid(path);
ItemAction ia;
ia.action = ItemAction::ACTION_FILE_REIMPORT;
@@ -663,6 +673,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
fi->modified_time = fc->modification_time;
fi->deps = fc->deps;
fi->import_modified_time = 0;
+ fi->import_valid = true;
} else {
//new or modified time
fi->type = ResourceLoader::get_resource_type(path);
@@ -670,6 +681,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
print_line("regular import tried resource type for " + path + " and its " + fi->type);
fi->modified_time = mt;
fi->import_modified_time = 0;
+ fi->import_valid = true;
}
}
@@ -766,6 +778,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
fi->modified_time = FileAccess::get_modified_time(path);
fi->import_modified_time = 0;
fi->type = ResourceLoader::get_resource_type(path);
+ fi->import_valid = ResourceLoader::is_import_valid(path);
{
ItemAction ia;
@@ -1036,7 +1049,7 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir,
for (int i = 0; i < p_dir->files.size(); i++) {
- String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time);
+ String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid);
s += "::";
for (int j = 0; j < p_dir->files[i]->deps.size(); j++) {
@@ -1217,7 +1230,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p
void EditorFileSystem::_save_late_updated_files() {
//files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file
- String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update2");
+ String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update3");
FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE);
for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) {
f->store_line(E->get());
@@ -1281,6 +1294,7 @@ void EditorFileSystem::update_file(const String &p_file) {
EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo);
fi->file = p_file.get_file();
fi->import_modified_time = 0;
+ fi->import_valid = ResourceLoader::is_import_valid(p_file);
if (idx == fs->files.size()) {
fs->files.push_back(fi);
@@ -1301,6 +1315,7 @@ void EditorFileSystem::update_file(const String &p_file) {
fs->files[cpos]->type = type;
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
fs->files[cpos]->deps = _get_dependencies(p_file);
+ fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file);
//if (FileAccess::exists(p_file+".import")) {
// fs->files[cpos]->import_modified_time=FileAccess::get_modified_time(p_file+".import");
//}
@@ -1368,7 +1383,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
}
}
- if (load_default && ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name())) {
+ if (load_default && ProjectSettings::get_singleton()->has("importer_defaults/" + importer->get_importer_name())) {
//use defaults if exist
Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name());
List<Variant> v;
@@ -1404,19 +1419,26 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
f->store_line("type=\"" + importer->get_resource_type() + "\"");
}
- if (importer->get_save_extension() == "") {
- //no path
- } else if (import_variants.size()) {
- //import with variants
- for (List<String>::Element *E = import_variants.front(); E; E = E->next()) {
+ if (err == OK) {
- String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension();
+ if (importer->get_save_extension() == "") {
+ //no path
+ } else if (import_variants.size()) {
+ //import with variants
+ for (List<String>::Element *E = import_variants.front(); E; E = E->next()) {
- f->store_line("path." + E->get() + "=\"" + path + "\"");
+ String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension();
+
+ f->store_line("path." + E->get() + "=\"" + path + "\"");
+ }
+ } else {
+
+ f->store_line("path=\"" + base_path + "." + importer->get_save_extension() + "\"");
}
+
} else {
- f->store_line("path=\"" + base_path + "." + importer->get_save_extension() + "\"");
+ f->store_line("valid=false");
}
f->store_line("");
@@ -1455,6 +1477,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import");
fs->files[cpos]->deps = _get_dependencies(p_file);
fs->files[cpos]->type = importer->get_resource_type();
+ fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file);
//if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it
//to reload properly
@@ -1486,6 +1509,8 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
if (!is_scanning()) {
emit_signal("filesystem_changed");
}
+
+ emit_signal("resources_reimported", p_files);
}
void EditorFileSystem::_bind_methods() {
@@ -1501,6 +1526,7 @@ void EditorFileSystem::_bind_methods() {
ADD_SIGNAL(MethodInfo("filesystem_changed"));
ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist")));
+ ADD_SIGNAL(MethodInfo("resources_reimported", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources")));
}
void EditorFileSystem::_update_extensions() {
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index 4d9a96d233..cee3219b43 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -54,6 +54,7 @@ class EditorFileSystemDirectory : public Object {
StringName type;
uint64_t modified_time;
uint64_t import_modified_time;
+ bool import_valid;
Vector<String> deps;
bool verified; //used for checking changes
};
@@ -83,6 +84,7 @@ public:
String get_file_path(int p_idx) const;
StringName get_file_type(int p_idx) const;
Vector<String> get_file_deps(int p_idx) const;
+ bool get_file_import_is_valid(int p_idx) const;
EditorFileSystemDirectory *get_parent();
@@ -153,6 +155,7 @@ class EditorFileSystem : public Node {
uint64_t modification_time;
uint64_t import_modification_time;
Vector<String> deps;
+ bool import_valid;
};
HashMap<String, FileCache> file_cache;
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index c4ac4cbca5..3ab3f05906 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -65,52 +65,55 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p
return font;
}
-#define MAKE_FALLBACKS(m_name) \
- m_name->add_fallback(DroidSansFallback); \
- m_name->add_fallback(DroidSansJapanese); \
- m_name->add_fallback(DroidSansArabic); \
- m_name->add_fallback(DroidSansHebrew); \
- m_name->add_fallback(DroidSansThai);
-
-#define MAKE_DROID_SANS(m_name, m_size) \
- Ref<DynamicFont> m_name; \
- m_name.instance(); \
- m_name->set_size(m_size); \
- m_name->set_font_data(DroidSans); \
+#define MAKE_FALLBACKS(m_name) \
+ m_name->add_fallback(FontArabic); \
+ m_name->add_fallback(FontHebrew); \
+ m_name->add_fallback(FontThai); \
+ m_name->add_fallback(FontJapanese); \
+ m_name->add_fallback(FontFallback);
+
+// the custom spacings might only work with Noto Sans
+#define MAKE_DEFAULT_FONT(m_name, m_size) \
+ Ref<DynamicFont> m_name; \
+ m_name.instance(); \
+ m_name->set_size(m_size); \
+ m_name->set_font_data(DefaultFont); \
+ m_name->set_spacing(DynamicFont::SPACING_TOP, -1); \
+ m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -1); \
MAKE_FALLBACKS(m_name);
void editor_register_fonts(Ref<Theme> p_theme) {
/* Droid Sans */
- Ref<DynamicFontData> DroidSans;
- DroidSans.instance();
- DroidSans->set_font_ptr(_font_DroidSans, _font_DroidSans_size);
- DroidSans->set_force_autohinter(true); //just looks better..i think?
+ Ref<DynamicFontData> DefaultFont;
+ DefaultFont.instance();
+ DefaultFont->set_font_ptr(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size);
+ DefaultFont->set_force_autohinter(true); //just looks better..i think?
- Ref<DynamicFontData> DroidSansFallback;
- DroidSansFallback.instance();
- DroidSansFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size);
- DroidSansFallback->set_force_autohinter(true); //just looks better..i think?
+ Ref<DynamicFontData> FontFallback;
+ FontFallback.instance();
+ FontFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size);
+ FontFallback->set_force_autohinter(true); //just looks better..i think?
- Ref<DynamicFontData> DroidSansJapanese;
- DroidSansJapanese.instance();
- DroidSansJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size);
- DroidSansJapanese->set_force_autohinter(true); //just looks better..i think?
+ Ref<DynamicFontData> FontJapanese;
+ FontJapanese.instance();
+ FontJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size);
+ FontJapanese->set_force_autohinter(true); //just looks better..i think?
- Ref<DynamicFontData> DroidSansArabic;
- DroidSansArabic.instance();
- DroidSansArabic->set_font_ptr(_font_DroidSansArabic, _font_DroidSansArabic_size);
- DroidSansArabic->set_force_autohinter(true); //just looks better..i think?
+ Ref<DynamicFontData> FontArabic;
+ FontArabic.instance();
+ FontArabic->set_font_ptr(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size);
+ FontArabic->set_force_autohinter(true); //just looks better..i think?
- Ref<DynamicFontData> DroidSansHebrew;
- DroidSansHebrew.instance();
- DroidSansHebrew->set_font_ptr(_font_DroidSansHebrew, _font_DroidSansHebrew_size);
- DroidSansHebrew->set_force_autohinter(true); //just looks better..i think?
+ Ref<DynamicFontData> FontHebrew;
+ FontHebrew.instance();
+ FontHebrew->set_font_ptr(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size);
+ FontHebrew->set_force_autohinter(true); //just looks better..i think?
- Ref<DynamicFontData> DroidSansThai;
- DroidSansThai.instance();
- DroidSansThai->set_font_ptr(_font_DroidSansThai, _font_DroidSansThai_size);
- DroidSansThai->set_force_autohinter(true); //just looks better..i think?
+ Ref<DynamicFontData> FontThai;
+ FontThai.instance();
+ FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size);
+ FontThai->set_force_autohinter(true); //just looks better..i think?
/* Source Code Pro */
@@ -119,7 +122,7 @@ void editor_register_fonts(Ref<Theme> p_theme) {
dfmono->set_font_ptr(_font_source_code_pro, _font_source_code_pro_size);
//dfd->set_force_autohinter(true); //just looks better..i think?
- MAKE_DROID_SANS(df, int(EditorSettings::get_singleton()->get("interface/font_size")) * EDSCALE);
+ MAKE_DEFAULT_FONT(df, int(EditorSettings::get_singleton()->get("interface/font_size")) * EDSCALE);
p_theme->set_default_theme_font(df);
@@ -127,9 +130,9 @@ void editor_register_fonts(Ref<Theme> p_theme) {
//Ref<BitmapFont> doc_title_font = make_font(_bi_font_doc_title_font_height,_bi_font_doc_title_font_ascent,0,_bi_font_doc_title_font_charcount,_bi_font_doc_title_font_characters,p_theme->get_icon("DocTitleFont","EditorIcons"));
//Ref<BitmapFont> doc_code_font = make_font(_bi_font_doc_code_font_height,_bi_font_doc_code_font_ascent,0,_bi_font_doc_code_font_charcount,_bi_font_doc_code_font_characters,p_theme->get_icon("DocCodeFont","EditorIcons"));
- MAKE_DROID_SANS(df_title, int(EDITOR_DEF("text_editor/help/help_title_font_size", 18)) * EDSCALE);
+ MAKE_DEFAULT_FONT(df_title, int(EDITOR_DEF("text_editor/help/help_title_font_size", 18)) * EDSCALE);
- MAKE_DROID_SANS(df_doc, int(EDITOR_DEF("text_editor/help/help_font_size", 16)) * EDSCALE);
+ MAKE_DEFAULT_FONT(df_doc, int(EDITOR_DEF("text_editor/help/help_font_size", 16)) * EDSCALE);
p_theme->set_font("doc", "EditorFonts", df_doc);
p_theme->set_font("doc_title", "EditorFonts", df_title);
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index c7c3a88684..c9d1548bfb 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -263,19 +263,22 @@ void EditorHelpSearch::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
+ //_update_icons
search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
connect("confirmed", this, "_confirmed");
_update_search();
- }
-
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
if (is_visible_in_tree()) {
search_box->call_deferred("grab_focus"); // still not visible
search_box->select_all();
}
+ } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+
+ //_update_icons
+ search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
}
}
@@ -385,6 +388,7 @@ void EditorHelpIndex::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
+ //_update_icons
search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
_update_class_list();
@@ -393,6 +397,10 @@ void EditorHelpIndex::_notification(int p_what) {
} else if (p_what == NOTIFICATION_POST_POPUP) {
search_box->call_deferred("grab_focus");
+ } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+
+ //_update_icons
+ search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
}
}
@@ -1703,12 +1711,6 @@ void EditorHelp::_notification(int p_what) {
_update_doc();
} break;
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- Ref<StyleBoxFlat> style(memnew(StyleBoxFlat));
- style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color"));
- background_panel->add_style_override("panel", style);
- } break;
-
default: break;
}
}
@@ -1778,14 +1780,11 @@ EditorHelp::EditorHelp() {
{
background_panel = memnew(Panel);
- Ref<StyleBoxFlat> style(memnew(StyleBoxFlat));
- style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color"));
background_panel->set_v_size_flags(SIZE_EXPAND_FILL);
- background_panel->add_style_override("panel", style); //get_stylebox("normal","TextEdit"));
vbc->add_child(background_panel);
class_desc = memnew(RichTextLabel);
background_panel->add_child(class_desc);
- class_desc->set_area_as_parent_rect(8);
+ class_desc->set_area_as_parent_rect();
class_desc->connect("meta_clicked", this, "_class_desc_select");
class_desc->connect("gui_input", this, "_class_desc_input");
}
@@ -1873,10 +1872,6 @@ void EditorHelpBit::_bind_methods() {
}
void EditorHelpBit::_notification(int p_what) {
-
- if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- add_style_override("panel", get_stylebox("ScriptPanel", "EditorStyles"));
- }
}
void EditorHelpBit::set_text(const String &p_text) {
@@ -1889,8 +1884,7 @@ EditorHelpBit::EditorHelpBit() {
rich_text = memnew(RichTextLabel);
add_child(rich_text);
- rich_text->set_area_as_parent_rect(8 * EDSCALE);
+ rich_text->set_area_as_parent_rect();
rich_text->connect("meta_clicked", this, "_meta_clicked");
set_custom_minimum_size(Size2(0, 70 * EDSCALE));
- add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index c376efca34..0db50ba0f3 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -296,6 +296,35 @@ void EditorNode::_notification(int p_what) {
scene_tabs->set_min_width(0);
}
_update_scene_tabs();
+
+ //_update_icons
+ for (int i = 0; i < singleton->main_editor_buttons.size(); i++) {
+ main_editor_buttons[i]->set_icon(gui_base->get_icon(singleton->main_editor_buttons[i]->get_name(), "EditorIcons"));
+ }
+ play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons"));
+ play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
+ play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
+ pause_button->set_icon(gui_base->get_icon("Pause", "EditorIcons"));
+ stop_button->set_icon(gui_base->get_icon("Stop", "EditorIcons"));
+
+ prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons"));
+ distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
+
+ resource_new_button->set_icon(gui_base->get_icon("New", "EditorIcons"));
+ resource_load_button->set_icon(gui_base->get_icon("Load", "EditorIcons"));
+ resource_save_button->set_icon(gui_base->get_icon("Save", "EditorIcons"));
+
+ property_back->set_icon(gui_base->get_icon("Back", "EditorIcons"));
+ property_forward->set_icon(gui_base->get_icon("Forward", "EditorIcons"));
+ editor_history_menu->set_icon(gui_base->get_icon("History", "EditorIcons"));
+
+ search_button->set_icon(gui_base->get_icon("Search", "EditorIcons"));
+ object_menu->set_icon(gui_base->get_icon("Tools", "EditorIcons"));
+ // clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); dont have access to that node. needs to become a class property
+ update_menu->set_icon(gui_base->get_icon("Collapse", "EditorIcons"));
+ dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons"));
+ dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons"));
+ update_menu->set_icon(gui_base->get_icon("Progress1", "EditorIcons"));
}
}
@@ -353,20 +382,23 @@ void EditorNode::_fs_changed() {
continue;
if (E->get()->get_import_path() != String()) {
- //imported resource
+//this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback
+//imported resource
+#if 0
uint64_t mt = FileAccess::get_modified_time(E->get()->get_import_path());
if (mt != E->get()->get_import_last_modified_time()) {
print_line("success");
changed.push_back(E->get());
}
+#endif
+ continue;
+ }
- } else {
- uint64_t mt = FileAccess::get_modified_time(E->get()->get_path());
+ uint64_t mt = FileAccess::get_modified_time(E->get()->get_path());
- if (mt != E->get()->get_last_modified_time()) {
- changed.push_back(E->get());
- }
+ if (mt != E->get()->get_last_modified_time()) {
+ changed.push_back(E->get());
}
}
@@ -381,6 +413,33 @@ void EditorNode::_fs_changed() {
_mark_unsaved_scenes();
}
+void EditorNode::_resources_reimported(const Vector<String> &p_resources) {
+ print_line("reimporting");
+ List<String> scenes; //will load later
+
+ for (int i = 0; i < p_resources.size(); i++) {
+ String file_type = ResourceLoader::get_resource_type(p_resources[i]);
+ if (file_type == "PackedScene") {
+ scenes.push_back(p_resources[i]);
+ //reload later if needed, first go with normal resources
+ continue;
+ }
+
+ if (!ResourceCache::has(p_resources[i])) {
+ continue; //not loaded, no need to reload
+ }
+ //reload normally
+ Resource *resource = ResourceCache::get(p_resources[i]);
+ if (resource) {
+ resource->reload_from_file();
+ }
+ }
+
+ for (List<String>::Element *E = scenes.front(); E; E = E->next()) {
+ reload_scene(E->get());
+ }
+}
+
void EditorNode::_sources_changed(bool p_exist) {
if (waiting_for_first_scan) {
@@ -559,7 +618,7 @@ void EditorNode::_menu_confirm_current() {
_menu_option_confirm(current_option, true);
}
-void EditorNode::_dialog_display_file_error(String p_file, Error p_error) {
+void EditorNode::_dialog_display_save_error(String p_file, Error p_error) {
if (p_error) {
@@ -586,6 +645,41 @@ void EditorNode::_dialog_display_file_error(String p_file, Error p_error) {
}
}
+void EditorNode::_dialog_display_load_error(String p_file, Error p_error) {
+
+ if (p_error) {
+
+ current_option = -1;
+ accept->get_ok()->set_text(TTR("I see.."));
+
+ switch (p_error) {
+
+ case ERR_CANT_OPEN: {
+
+ accept->set_text(vformat(TTR("Can't open '%s'."), p_file.get_file()));
+ } break;
+ case ERR_PARSE_ERROR: {
+
+ accept->set_text(vformat(TTR("Error while parsing '%s'."), p_file.get_file()));
+ } break;
+ case ERR_FILE_CORRUPT: {
+
+ accept->set_text(vformat(TTR("Unexpected end of file '%s'."), p_file.get_file()));
+ } break;
+ case ERR_FILE_NOT_FOUND: {
+
+ accept->set_text(vformat(TTR("Missing '%s' or its dependencies."), p_file.get_file()));
+ } break;
+ default: {
+
+ accept->set_text(vformat(TTR("Error while loading '%s'."), p_file.get_file()));
+ } break;
+ }
+
+ accept->popup_centered_minsize();
+ }
+}
+
void EditorNode::_get_scene_metadata(const String &p_file) {
Node *scene = editor_data.get_edited_scene_root();
@@ -899,7 +993,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
_update_scene_tabs();
} else {
- _dialog_display_file_error(p_file, err);
+ _dialog_display_save_error(p_file, err);
}
}
@@ -908,8 +1002,10 @@ void EditorNode::_save_all_scenes() {
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
Node *scene = editor_data.get_edited_scene_root(i);
if (scene && scene->get_filename() != "") {
- // save in background if in the script editor
- _save_scene_with_preview(scene->get_filename());
+ if (i != editor_data.get_edited_scene())
+ _save_scene(scene->get_filename(), i);
+ else
+ _save_scene_with_preview(scene->get_filename());
} // else: ignore new scenes
}
@@ -983,7 +1079,10 @@ void EditorNode::_dialog_action(String p_file) {
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
_save_default_environment();
- _save_scene_with_preview(p_file);
+ if (scene_idx != editor_data.get_edited_scene())
+ _save_scene(p_file, scene_idx);
+ else
+ _save_scene_with_preview(p_file);
if (scene_idx != -1)
_discard_changes();
@@ -996,7 +1095,6 @@ void EditorNode::_dialog_action(String p_file) {
_save_default_environment();
_save_scene_with_preview(p_file);
- _call_build();
_run(true);
}
} break;
@@ -1270,12 +1368,22 @@ void EditorNode::_set_editing_top_editors(Object *p_current_object) {
editor_plugins_over->edit(p_current_object);
}
+static bool overrides_external_editor(Object *p_object) {
+
+ Script *script = Object::cast_to<Script>(p_object);
+
+ if (!script)
+ return false;
+
+ return script->get_language()->overrides_external_editor();
+}
+
void EditorNode::_edit_current() {
uint32_t current = editor_history.get_current();
Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
- property_back->set_disabled(editor_history.is_at_begining());
+ property_back->set_disabled(editor_history.is_at_beginning());
property_forward->set_disabled(editor_history.is_at_end());
this->current = current_obj;
@@ -1336,7 +1444,7 @@ void EditorNode::_edit_current() {
if (main_plugin) {
// special case if use of external editor is true
- if (main_plugin->get_name() == "Script" && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
+ if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
main_plugin->edit(current_obj);
}
@@ -1344,6 +1452,7 @@ void EditorNode::_edit_current() {
// update screen main_plugin
if (!changing_scene) {
+
if (editor_plugin_screen)
editor_plugin_screen->make_visible(false);
editor_plugin_screen = main_plugin;
@@ -1546,6 +1655,9 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
editor_data.save_editor_external_data();
}
+ if (!_call_build())
+ return;
+
if (bool(EDITOR_DEF("run/output/always_clear_output_on_play", true))) {
log->clear();
}
@@ -1660,8 +1772,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
Node *scene = editor_data.get_edited_scene_root(scene_idx);
if (scene && scene->get_filename() != "") {
- // save in background if in the script editor
- _save_scene_with_preview(scene->get_filename());
+ if (scene_idx != editor_data.get_edited_scene())
+ _save_scene(scene->get_filename(), scene_idx);
+ else
+ _save_scene_with_preview(scene->get_filename());
if (scene_idx != -1)
_discard_changes();
@@ -2003,7 +2117,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_PLAY: {
_menu_option_confirm(RUN_STOP, true);
- _call_build();
_run(false);
} break;
@@ -2048,7 +2161,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
_save_default_environment();
_menu_option_confirm(RUN_STOP, true);
- _call_build();
_run(true);
} break;
@@ -2060,7 +2172,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
if (run_native->is_deploy_debug_remote_enabled()) {
_menu_option_confirm(RUN_STOP, true);
- _call_build();
+
+ if (!_call_build())
+ break; // build failed
+
emit_signal("play_pressed");
editor_run.run_native_notify();
}
@@ -2183,14 +2298,19 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
update_menu->get_popup()->set_item_checked(0, true);
update_menu->get_popup()->set_item_checked(1, false);
OS::get_singleton()->set_low_processor_usage_mode(false);
- EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_mode", SETTINGS_UPDATE_ALWAYS);
+ EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_always", true);
+
+ current_option = -1;
+ accept->get_ok()->set_text(TTR("I see.."));
+ accept->set_text(TTR("This option is deprecated. Situations where refresh must be forced are now considered a bug. Please report."));
+ accept->popup_centered_minsize();
} break;
case SETTINGS_UPDATE_CHANGES: {
update_menu->get_popup()->set_item_checked(0, false);
update_menu->get_popup()->set_item_checked(1, true);
OS::get_singleton()->set_low_processor_usage_mode(true);
- EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_mode", SETTINGS_UPDATE_CHANGES);
+ EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_always", false);
} break;
case SETTINGS_UPDATE_SPINNER_HIDE: {
@@ -2612,6 +2732,14 @@ Dictionary EditorNode::_get_main_scene_state() {
state["property_edit_offset"] = get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_value();
state["saved_version"] = saved_version;
state["node_filter"] = scene_tree_dock->get_filter();
+ int current = -1;
+ for (int i = 0; i < editor_table.size(); i++) {
+ if (editor_plugin_screen == editor_table[i]) {
+ current = i;
+ break;
+ }
+ }
+ state["editor_index"] = current;
return state;
}
@@ -2622,8 +2750,9 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
changing_scene = false;
- if (get_edited_scene()) {
+ if (p_state.has("editor_index")) {
+ int index = p_state["editor_index"];
int current = -1;
for (int i = 0; i < editor_table.size(); i++) {
if (editor_plugin_screen == editor_table[i]) {
@@ -2632,15 +2761,18 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
}
}
- if (current < 2) {
- //use heuristic instead
-
- int n2d = 0, n3d = 0;
- _find_node_types(get_edited_scene(), n2d, n3d);
- if (n2d > n3d) {
- _editor_select(EDITOR_2D);
- } else if (n3d > n2d) {
- _editor_select(EDITOR_3D);
+ if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there
+ if (index < 2 || !get_edited_scene()) {
+ _editor_select(index);
+ } else {
+ //use heuristic instead
+ int n2d = 0, n3d = 0;
+ _find_node_types(get_edited_scene(), n2d, n3d);
+ if (n2d > n3d) {
+ _editor_select(EDITOR_2D);
+ } else if (n3d > n2d) {
+ _editor_select(EDITOR_3D);
+ }
}
}
}
@@ -2778,13 +2910,12 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
dependency_errors.clear();
- Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true);
+ print_line("actually loading it");
+ Error err;
+ Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err);
if (!sdata.is_valid()) {
- current_option = -1;
- accept->get_ok()->set_text(TTR("Ugh"));
- accept->set_text(TTR("Error loading scene."));
- accept->popup_centered_minsize();
+ _dialog_display_load_error(lpath, err);
opening_prev = false;
if (prev != -1) {
@@ -2841,10 +2972,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
if (!new_scene) {
sdata.unref();
- current_option = -1;
- accept->get_ok()->set_text(TTR("Ugh"));
- accept->set_text(TTR("Error loading scene."));
- accept->popup_centered_minsize();
+ _dialog_display_load_error(lpath, ERR_FILE_NOT_FOUND);
opening_prev = false;
if (prev != -1) {
set_current_scene(prev);
@@ -3014,7 +3142,6 @@ void EditorNode::_quick_opened() {
void EditorNode::_quick_run() {
- _call_build();
_run(false, quick_run->get_selected());
}
@@ -4106,30 +4233,25 @@ void EditorNode::_file_access_close_error_notify(const String &p_str) {
void EditorNode::reload_scene(const String &p_path) {
- //first of all, reload textures as they might have changed on disk
+ //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk
+ print_line("reloading: " + p_path);
List<Ref<Resource> > cached;
ResourceCache::get_cached_resources(&cached);
List<Ref<Resource> > to_clear; //clear internal resources from previous scene from being used
for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) {
- if (E->get()->get_path().begins_with(p_path + "::")) //subresources of existing scene
+ if (E->get()->get_path().find("::") != -1) {
+ print_line(E->get()->get_path());
+ }
+ if (E->get()->get_path().begins_with(p_path + "::")) { //subresources of existing scene
to_clear.push_back(E->get());
-
- if (!cast_to<Texture>(E->get().ptr()))
- continue;
- if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path())
- continue;
- if (!FileAccess::exists(E->get()->get_path()))
- continue;
- uint64_t mt = FileAccess::get_modified_time(E->get()->get_path());
- if (mt != E->get()->get_last_modified_time()) {
- E->get()->reload_from_file();
}
}
//so reload reloads everything, clear subresources of previous scene
while (to_clear.front()) {
+ print_line("bye bye: " + to_clear.front()->get()->get_path());
to_clear.front()->get()->set_path("");
to_clear.pop_front();
}
@@ -4161,7 +4283,8 @@ void EditorNode::reload_scene(const String &p_path) {
//remove scene
_remove_scene(scene_idx);
//reload scene
- load_scene(p_path);
+
+ load_scene(p_path, true, false, true, true);
//adjust index so tab is back a the previous position
editor_data.move_edited_scene_to_index(scene_idx);
get_undo_redo()->clear_history();
@@ -4190,13 +4313,16 @@ void EditorNode::add_build_callback(EditorBuildCallback p_callback) {
build_callbacks[build_callback_count++] = p_callback;
}
-EditorPluginInitializeCallback EditorNode::build_callbacks[EditorNode::MAX_BUILD_CALLBACKS];
+EditorBuildCallback EditorNode::build_callbacks[EditorNode::MAX_BUILD_CALLBACKS];
-void EditorNode::_call_build() {
+bool EditorNode::_call_build() {
for (int i = 0; i < build_callback_count; i++) {
- build_callbacks[i]();
+ if (!build_callbacks[i]())
+ return false;
}
+
+ return true;
}
void EditorNode::_inherit_imported(const String &p_action) {
@@ -4350,6 +4476,8 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout);
ClassDB::bind_method(D_METHOD("_check_gui_base_size"), &EditorNode::_check_gui_base_size);
+ ClassDB::bind_method(D_METHOD("_resources_reimported"), &EditorNode::_resources_reimported);
+
ADD_SIGNAL(MethodInfo("play_pressed"));
ADD_SIGNAL(MethodInfo("pause_pressed"));
ADD_SIGNAL(MethodInfo("stop_pressed"));
@@ -4726,6 +4854,38 @@ EditorNode::EditorNode() {
prev_scene->set_position(Point2(3, 24));
prev_scene->hide();
+ accept = memnew(AcceptDialog);
+ gui_base->add_child(accept);
+ accept->connect("confirmed", this, "_menu_confirm_current");
+
+ project_export = memnew(ProjectExportDialog);
+ gui_base->add_child(project_export);
+
+ dependency_error = memnew(DependencyErrorDialog);
+ gui_base->add_child(dependency_error);
+
+ dependency_fixer = memnew(DependencyEditor);
+ gui_base->add_child(dependency_fixer);
+
+ settings_config_dialog = memnew(EditorSettingsDialog);
+ gui_base->add_child(settings_config_dialog);
+
+ project_settings = memnew(ProjectSettingsEditor(&editor_data));
+ gui_base->add_child(project_settings);
+
+ run_settings_dialog = memnew(RunSettingsDialog);
+ gui_base->add_child(run_settings_dialog);
+
+ export_template_manager = memnew(ExportTemplateManager);
+ gui_base->add_child(export_template_manager);
+
+ about = memnew(EditorAbout);
+ about->get_logo()->set_texture(gui_base->get_icon("Logo", "EditorIcons"));
+ gui_base->add_child(about);
+
+ warning = memnew(AcceptDialog);
+ gui_base->add_child(warning);
+
ED_SHORTCUT("editor/next_tab", TTR("Next tab"), KEY_MASK_CMD + KEY_TAB);
ED_SHORTCUT("editor/prev_tab", TTR("Previous tab"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_TAB);
ED_SHORTCUT("editor/filter_files", TTR("Filter Files.."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_P);
@@ -4752,7 +4912,6 @@ EditorNode::EditorNode() {
pm_export->set_name("Export");
p->add_child(pm_export);
p->add_submenu_item(TTR("Convert To.."), "Export");
- pm_export->add_separator();
pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_MeshLibrary", TTR("MeshLibrary..")), FILE_EXPORT_MESH_LIBRARY);
pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_TileSet", TTR("TileSet..")), FILE_EXPORT_TILESET);
pm_export->connect("id_pressed", this, "_menu_option");
@@ -4870,7 +5029,7 @@ EditorNode::EditorNode() {
play_cc->set_margin(MARGIN_TOP, 5);
play_button_panel = memnew(PanelContainer);
- play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles"));
+ // play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles"));
play_cc->add_child(play_button_panel);
HBoxContainer *play_hb = memnew(HBoxContainer);
@@ -4950,9 +5109,9 @@ EditorNode::EditorNode() {
p->add_check_item(TTR("Update Changes"), SETTINGS_UPDATE_CHANGES);
p->add_separator();
p->add_check_item(TTR("Disable Update Spinner"), SETTINGS_UPDATE_SPINNER_HIDE);
- int update_mode = EditorSettings::get_singleton()->get_project_metadata("editor_options", "update_mode", SETTINGS_UPDATE_CHANGES);
+ int update_always = EditorSettings::get_singleton()->get_project_metadata("editor_options", "update_always", false);
int hide_spinner = EditorSettings::get_singleton()->get_project_metadata("editor_options", "update_spinner_hide", false);
- _menu_option(update_mode);
+ _menu_option(update_always ? SETTINGS_UPDATE_ALWAYS : SETTINGS_UPDATE_CHANGES);
if (hide_spinner) {
_menu_option(SETTINGS_UPDATE_SPINNER_HIDE);
}
@@ -5150,38 +5309,6 @@ EditorNode::EditorNode() {
save_confirmation->connect("confirmed", this, "_menu_confirm_current");
save_confirmation->connect("custom_action", this, "_discard_changes");
- accept = memnew(AcceptDialog);
- gui_base->add_child(accept);
- accept->connect("confirmed", this, "_menu_confirm_current");
-
- project_export = memnew(ProjectExportDialog);
- gui_base->add_child(project_export);
-
- dependency_error = memnew(DependencyErrorDialog);
- gui_base->add_child(dependency_error);
-
- dependency_fixer = memnew(DependencyEditor);
- gui_base->add_child(dependency_fixer);
-
- settings_config_dialog = memnew(EditorSettingsDialog);
- gui_base->add_child(settings_config_dialog);
-
- project_settings = memnew(ProjectSettingsEditor(&editor_data));
- gui_base->add_child(project_settings);
-
- run_settings_dialog = memnew(RunSettingsDialog);
- gui_base->add_child(run_settings_dialog);
-
- export_template_manager = memnew(ExportTemplateManager);
- gui_base->add_child(export_template_manager);
-
- about = memnew(EditorAbout);
- about->get_logo()->set_texture(gui_base->get_icon("Logo", "EditorIcons"));
- gui_base->add_child(about);
-
- warning = memnew(AcceptDialog);
- gui_base->add_child(warning);
-
file_templates = memnew(FileDialog);
file_templates->set_title(TTR("Import Templates From ZIP File"));
@@ -5378,6 +5505,7 @@ EditorNode::EditorNode() {
EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed");
EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed");
+ EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported");
{
List<StringName> tl;
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 08c7e11c85..c3ceee350a 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -85,7 +85,7 @@
typedef void (*EditorNodeInitCallback)();
typedef void (*EditorPluginInitializeCallback)();
-typedef void (*EditorBuildCallback)();
+typedef bool (*EditorBuildCallback)();
class EditorPluginList;
@@ -404,7 +404,8 @@ private:
void _dialog_action(String p_file);
void _edit_current();
- void _dialog_display_file_error(String p_file, Error p_error);
+ void _dialog_display_save_error(String p_file, Error p_error);
+ void _dialog_display_load_error(String p_file, Error p_error);
int current_option;
void _resource_created();
@@ -421,6 +422,7 @@ private:
void _prepare_history();
void _fs_changed();
+ void _resources_reimported(const Vector<String> &p_resources);
void _sources_changed(bool p_exist);
void _node_renamed();
@@ -574,7 +576,7 @@ private:
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
void _save_default_environment();
- void _call_build();
+ bool _call_build();
static int build_callback_count;
static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index 92768dfe91..0587939a1a 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -160,7 +160,7 @@ void EditorPath::_notification(int p_what) {
set_tooltip(obj->get_class());
- label_font->draw(ci, Point2i(ofs, (size.height - label_font->get_height()) / 2 + label_font->get_ascent()), name, Color(1, 1, 1), left);
+ label_font->draw(ci, Point2i(ofs, (size.height - label_font->get_height()) / 2 + label_font->get_ascent()), name, get_color("font_color", "Label"), left);
} else {
//add arrow
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index b5d881ad5c..86acfcc50e 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -590,9 +590,9 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorPlugin::get_editor_interface);
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_canvas_gui_input", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_canvas", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::OBJECT, "canvas:Control")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_canvas", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::OBJECT, "canvas", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- MethodInfo gizmo = MethodInfo(Variant::OBJECT, "create_spatial_gizmo", PropertyInfo(Variant::OBJECT, "for_spatial:Spatial"));
+ MethodInfo gizmo = MethodInfo(Variant::OBJECT, "create_spatial_gizmo", PropertyInfo(Variant::OBJECT, "for_spatial", PROPERTY_HINT_RESOURCE_TYPE, "Spatial"));
gizmo.return_val.hint = PROPERTY_HINT_RESOURCE_TYPE;
gizmo.return_val.hint_string = "EditorSpatialGizmo";
ClassDB::add_virtual_method(get_class_static(), gizmo);
@@ -610,9 +610,9 @@ void EditorPlugin::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), MethodInfo("set_window_layout", PropertyInfo(Variant::OBJECT, "layout", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("get_window_layout", PropertyInfo(Variant::OBJECT, "layout", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile")));
- ADD_SIGNAL(MethodInfo("scene_changed", PropertyInfo(Variant::OBJECT, "scene_root:Node")));
- ADD_SIGNAL(MethodInfo("scene_closed", PropertyInfo(Variant::STRING, "filepath:String")));
- ADD_SIGNAL(MethodInfo("main_screen_changed", PropertyInfo(Variant::STRING, "screen_name:String")));
+ ADD_SIGNAL(MethodInfo("scene_changed", PropertyInfo(Variant::OBJECT, "scene_root", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
+ ADD_SIGNAL(MethodInfo("scene_closed", PropertyInfo(Variant::STRING, "filepath")));
+ ADD_SIGNAL(MethodInfo("main_screen_changed", PropertyInfo(Variant::STRING, "screen_name")));
BIND_ENUM_CONSTANT(CONTAINER_TOOLBAR);
BIND_ENUM_CONSTANT(CONTAINER_SPATIAL_EDITOR_MENU);
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index ee477b7c18..437ad5ac3f 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -69,8 +69,8 @@ Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_
void EditorResourcePreviewGenerator::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "handles", PropertyInfo(Variant::STRING, "type")));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::OBJECT, "generate:Texture", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::OBJECT, "generate_from_path:Texture", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE)));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate_from_path", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE)));
}
EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() {
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 6398bd1623..db76a27f5f 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -570,7 +570,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("interface/quit_confirmation", true);
set("interface/theme/preset", 0);
- hints["interface/theme/preset"] = PropertyInfo(Variant::INT, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Grey,Godot 2,Arc,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/theme/preset"] = PropertyInfo(Variant::INT, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Grey,Godot 2,Arc,Light,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ set("interface/theme/icon_and_font_color", 0);
+ hints["interface/theme/icon_and_font_color"] = PropertyInfo(Variant::INT, "interface/theme/icon_and_font_color", PROPERTY_HINT_ENUM, "Auto,Dark,Light", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/theme/base_color", Color::html("#323b4f"));
hints["interface/theme/highlight_color"] = PropertyInfo(Variant::COLOR, "interface/theme/highlight_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/theme/highlight_color", Color::html("#699ce8"));
@@ -591,7 +593,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("filesystem/directories/autoscan_project_path", "");
hints["filesystem/directories/autoscan_project_path"] = PropertyInfo(Variant::STRING, "filesystem/directories/autoscan_project_path", PROPERTY_HINT_GLOBAL_DIR);
- set("filesystem/directories/default_project_path", "");
+ set("filesystem/directories/default_project_path", OS::get_singleton()->has_environment("HOME") ? OS::get_singleton()->get_environment("HOME") : OS::get_singleton()->get_system_dir(OS::SYSTEM_DIR_DOCUMENTS));
hints["filesystem/directories/default_project_path"] = PropertyInfo(Variant::STRING, "filesystem/directories/default_project_path", PROPERTY_HINT_GLOBAL_DIR);
set("filesystem/directories/default_project_export_path", "");
hints["global/default_project_export_path"] = PropertyInfo(Variant::STRING, "global/default_project_export_path", PROPERTY_HINT_GLOBAL_DIR);
@@ -601,7 +603,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Default");
set("text_editor/theme/line_spacing", 4);
- set("text_editor/theme/adapted_code_editor_background_color", true);
_load_default_text_editor_theme();
@@ -614,6 +615,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["text_editor/indent/type"] = PropertyInfo(Variant::INT, "text_editor/indent/type", PROPERTY_HINT_ENUM, "Tabs,Spaces");
set("text_editor/indent/size", 4);
hints["text_editor/indent/size"] = PropertyInfo(Variant::INT, "text_editor/indent/size", PROPERTY_HINT_RANGE, "1, 64, 1"); // size of 0 crashes.
+ set("text_editor/indent/auto_indent", true);
set("text_editor/indent/convert_indent_on_save", false);
set("text_editor/indent/draw_tabs", true);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index a527701563..728801d90b 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -86,15 +86,17 @@ static Ref<StyleBoxFlat> change_border_color(Ref<StyleBoxFlat> p_style, Color p_
return style;
}
-#define HIGHLIGHT_COLOR_LIGHT highlight_color.linear_interpolate(Color(1, 1, 1, 1), 0.3)
-#define HIGHLIGHT_COLOR_DARK highlight_color.linear_interpolate(Color(0, 0, 0, 1), 0.5)
+Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true, Dictionary *p_colors = NULL) {
-Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true) {
Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
- ImageLoaderSVG::create_image_from_string(img, dark_theme ? editor_icons_sources[p_index] : editor_icons_sources_dark[p_index], EDSCALE, true);
- if ((EDSCALE - (float)((int)EDSCALE)) > 0.0)
+ // dumb gizmo check
+ bool is_gizmo = String(editor_icons_names[p_index]).begins_with("Gizmo");
+
+ ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], EDSCALE, true, dark_theme ? NULL : p_colors);
+
+ if ((EDSCALE - (float)((int)EDSCALE)) > 0.0 || is_gizmo)
icon->create_from_image(img); // in this case filter really helps
else
icon->create_from_image(img, 0);
@@ -102,19 +104,74 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true) {
return icon;
}
-void editor_register_icons(Ref<Theme> p_theme, bool dark_theme = true) {
+#ifndef ADD_CONVERT_COLOR
+#define ADD_CONVERT_COLOR(dictionary, old_color, new_color) dictionary[Color::html(old_color)] = Color::html(new_color)
+#endif
+
+void editor_register_and_generate_icons(Ref<Theme> p_theme, bool dark_theme = true) {
#ifdef SVG_ENABLED
- print_line(rtos(EDSCALE));
+
+ Dictionary dark_icon_color_dictionary;
+ //convert color: FROM TO
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#4f4f4f"); // common icon color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#000000"); // white
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#000000"); // script darker color
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cea4f1", "#bb6dff"); // animation
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc9c9c", "#ff5f5f"); // spatial
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5b7f3", "#6d90ff"); // 2d
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#708cea", "#0843ff"); // 2d dark
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5efac", "#29d739"); // control
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff3333"); // error
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00db50"); // success
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffd684", "#ffad07"); // warning
+
+ // rainbow
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff7070", "#ff2929"); // red
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffeb70", "#ffe337"); // yellow
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9dff70", "#74ff34"); // green
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70ffb9", "#2cff98"); // aqua
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70deff", "#22ccff"); // blue
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9f70ff", "#702aff"); // purple
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff70ac", "#ff2781"); // pink
+
+ // audio gradient
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff4040"); // red
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1dc7a", "#d6cf4b"); // yellow
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00f010"); // green
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffd684", "#fea900"); // mesh (orange)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#40a2ff", "#68b6ff"); // shape (blue)
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84c2ff", "#5caeff"); // selection (blue)
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea686c", "#e3383d"); // key xform (red)
+
+ List<String> exceptions;
+ exceptions.push_back("EditorPivot");
+ exceptions.push_back("EditorHandle");
+ exceptions.push_back("Editor3DHandle");
+ exceptions.push_back("Godot");
+ exceptions.push_back("PanoramaSky");
+ exceptions.push_back("ProceduralSky");
+ exceptions.push_back("EditorControlAnchor");
+ exceptions.push_back("DefaultProjectIcon");
clock_t begin_time = clock();
for (int i = 0; i < editor_icons_count; i++) {
-
- Ref<ImageTexture> icon = editor_generate_icon(i, dark_theme);
+ List<String>::Element *is_exception = exceptions.find(editor_icons_names[i]);
+ if (is_exception) {
+ exceptions.erase(is_exception);
+ }
+ Ref<ImageTexture> icon = editor_generate_icon(i, dark_theme, is_exception ? NULL : &dark_icon_color_dictionary);
p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
}
+
clock_t end_time = clock();
+
double time_d = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
print_line("SVG_GENERATION TIME: " + rtos(time_d));
#else
@@ -122,22 +179,27 @@ void editor_register_icons(Ref<Theme> p_theme, bool dark_theme = true) {
#endif
}
+#define HIGHLIGHT_COLOR_FONT highlight_color.linear_interpolate(dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1), 0.5)
+#define HIGHLIGHT_COLOR_BG highlight_color.linear_interpolate(dark_theme ? Color(0, 0, 0, 1) : Color(1, 1, 1, 1), 0.5)
+
Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Ref<Theme> theme = Ref<Theme>(memnew(Theme));
- editor_register_fonts(theme);
-
const float default_contrast = 0.25;
- // Define colors
+ //Theme settings
Color highlight_color = EDITOR_DEF("interface/theme/highlight_color", Color::html("#000000"));
Color base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#000000"));
float contrast = EDITOR_DEF("interface/theme/contrast", default_contrast);
+
int preset = EDITOR_DEF("interface/theme/preset", 0);
+ int icon_font_color_setting = EDITOR_DEF("interface/theme/icon_and_font_color", 0);
bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false);
int border_size = EDITOR_DEF("interface/theme/border_size", 1);
+ Color script_bg_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0));
+
switch (preset) {
case 0: { // Default
highlight_color = Color::html("#699ce8");
@@ -159,45 +221,40 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
base_color = Color::html("#383c4a");
contrast = 0.25;
} break;
+ case 4: { // Light
+ highlight_color = Color::html("#2070ff");
+ base_color = Color::html("#ffffff");
+ contrast = 0.08;
+ } break;
}
+ //Colors
+ int AUTO_COLOR = 0;
+ int LIGHT_COLOR = 2;
+ bool dark_theme = (icon_font_color_setting == AUTO_COLOR && ((base_color.r + base_color.g + base_color.b) / 3.0) < 0.5) || icon_font_color_setting == LIGHT_COLOR;
+
Color dark_color_1 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast);
Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5);
Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2);
- Color light_color_1 = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast);
- Color light_color_2 = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast * 1.5);
+ Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.3);
+ Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.5);
- const int border_width = CLAMP(border_size, 0, 3) * EDSCALE;
-
- Color title_color_hl = base_color;
- if (highlight_tabs)
- title_color_hl = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast / default_contrast / 10);
- bool dark_bg = ((title_color_hl.r + title_color_hl.g + title_color_hl.b) / 3.0) < 0.5;
- Color title_color_hl_text_color = dark_bg ? Color(1, 1, 1, 0.9) : Color(0, 0, 0, 0.9);
+ Color font_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0);
+ Color font_color_disabled = dark_theme ? Color(0.6, 0.6, 0.6) : Color(0.45, 0.45, 0.45);
- bool dark_theme = ((base_color.r + base_color.g + base_color.b) / 3.0) < 0.5;
Color separator_color = dark_theme ? Color(1, 1, 1, 0.1) : Color(0, 0, 0, 0.1);
- // the resolution or the dark theme parameter has not changed, so we do not regenerate the icons
- if (p_theme != NULL && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && p_theme->get_constant("dark_theme", "Editor") == dark_theme) {
- for (int i = 0; i < editor_icons_count; i++) {
- theme->set_icon(editor_icons_names[i], "EditorIcons", p_theme->get_icon(editor_icons_names[i], "EditorIcons"));
- }
- } else {
- editor_register_icons(theme, dark_theme);
- }
-
- theme->set_constant("scale", "Editor", EDSCALE);
- theme->set_constant("dark_theme", "Editor", dark_theme);
+ Color tab_color = highlight_tabs ? base_color.linear_interpolate(font_color, contrast) : base_color;
+ const int border_width = CLAMP(border_size, 0, 3) * EDSCALE;
theme->set_color("highlight_color", "Editor", highlight_color);
theme->set_color("base_color", "Editor", base_color);
theme->set_color("dark_color_1", "Editor", dark_color_1);
theme->set_color("dark_color_2", "Editor", dark_color_2);
theme->set_color("dark_color_3", "Editor", dark_color_3);
- theme->set_color("light_color_1", "Editor", light_color_1);
- theme->set_color("light_color_2", "Editor", light_color_2);
+ theme->set_color("contrast_color_1", "Editor", contrast_color_1);
+ theme->set_color("contrast_color_2", "Editor", contrast_color_2);
Color success_color = highlight_color.linear_interpolate(Color(.6, 1, .6), 0.8);
Color warning_color = highlight_color.linear_interpolate(Color(1, 1, .2), 0.8);
@@ -206,25 +263,31 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("warning_color", "Editor", warning_color);
theme->set_color("error_color", "Editor", error_color);
- // Checkbox icon
- theme->set_icon("checked", "CheckBox", theme->get_icon("GuiChecked", "EditorIcons"));
- theme->set_icon("unchecked", "CheckBox", theme->get_icon("GuiUnchecked", "EditorIcons"));
- theme->set_icon("checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
- theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
- theme->set_icon("radio_checked", "CheckBox", theme->get_icon("GuiRadioChecked", "EditorIcons"));
- theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon("GuiRadioUnchecked", "EditorIcons"));
- theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
- theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
+ theme->set_constant("scale", "Editor", EDSCALE);
+ theme->set_constant("dark_theme", "Editor", dark_theme);
+
+ //Register icons + font
+
+ // the resolution and the icon color (dark_theme bool) has not changed, so we do not regenerate the icons
+ if (p_theme != NULL && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && p_theme->get_constant("dark_theme", "Editor") == dark_theme) {
+ // register already generated icons
+ for (int i = 0; i < editor_icons_count; i++) {
+ theme->set_icon(editor_icons_names[i], "EditorIcons", p_theme->get_icon(editor_icons_names[i], "EditorIcons"));
+ }
+ } else {
+ editor_register_and_generate_icons(theme, dark_theme);
+ }
+
+ editor_register_fonts(theme);
// Editor background
- Ref<StyleBoxFlat> style_panel = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
- theme->set_stylebox("Background", "EditorStyles", style_panel);
+ theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(dark_color_2, 4, 4, 4, 4));
// Focus
- Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(light_color_1, 4, 4, 4, 4);
- focus_sbt->set_filled(false);
+ Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(contrast_color_1, 4, 4, 4, 4);
+ focus_sbt->set_draw_center(false);
focus_sbt->set_border_width_all(1 * EDSCALE);
- focus_sbt = change_border_color(focus_sbt, light_color_2);
+ focus_sbt = change_border_color(focus_sbt, contrast_color_2);
theme->set_stylebox("Focus", "EditorStyles", focus_sbt);
// Menu
@@ -233,17 +296,19 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("MenuPanel", "EditorStyles", style_menu);
// Play button group
- theme->set_stylebox("PlayButtonPanel", "EditorStyles", make_stylebox(theme->get_icon("GuiPlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4));
+ theme->set_stylebox("PlayButtonPanel", "EditorStyles", make_empty_stylebox(8, 4, 8, 4)); //make_stylebox(theme->get_icon("GuiPlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4));
+ //MenuButton
Ref<StyleBoxFlat> style_menu_hover_border = make_flat_stylebox(highlight_color, 4, 4, 4, 4);
Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
- style_menu_hover_border->set_filled(false);
+ style_menu_hover_border->set_draw_center(false);
style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width);
+ style_menu_hover_border->set_border_color_all(highlight_color);
style_menu_hover_border->set_expand_margin_size(MARGIN_BOTTOM, border_width);
theme->set_stylebox("normal", "MenuButton", style_menu);
- theme->set_stylebox("hover", "MenuButton", style_menu);
+ theme->set_stylebox("hover", "MenuButton", style_menu_hover_border);
theme->set_stylebox("pressed", "MenuButton", style_menu);
theme->set_stylebox("focus", "MenuButton", style_menu);
theme->set_stylebox("disabled", "MenuButton", style_menu);
@@ -260,58 +325,60 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("focus", "ToolButton", style_menu);
theme->set_stylebox("disabled", "ToolButton", style_menu);
- theme->set_color("font_color_hover", "MenuButton", HIGHLIGHT_COLOR_LIGHT);
- theme->set_color("font_color_hover", "ToolButton", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color", "MenuButton", font_color);
+ theme->set_color("font_color_hover", "MenuButton", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("font_color", "ToolButton", font_color);
+ theme->set_color("font_color_hover", "ToolButton", HIGHLIGHT_COLOR_FONT);
theme->set_color("font_color_pressed", "ToolButton", highlight_color);
theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border);
// Content of each tab
- Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 5, 4, 4);
- style_content_panel->set_border_color_all(title_color_hl);
+ Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 4, 4, 4);
+ style_content_panel->set_border_color_all(base_color);
style_content_panel->set_border_width_all(border_width);
- Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 5, border_width, border_width);
- style_content_panel_vp->set_border_color_all(title_color_hl);
+ Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 4, border_width, border_width);
+ style_content_panel_vp->set_border_color_all(base_color);
style_content_panel_vp->set_border_width_all(border_width);
theme->set_stylebox("panel", "TabContainer", style_content_panel);
theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp);
Ref<StyleBoxFlat> style_button_type = make_flat_stylebox(dark_color_1, 6, 4, 6, 4);
- style_button_type->set_filled(true);
+ style_button_type->set_draw_center(true);
style_button_type->set_border_width_all(border_width);
- style_button_type->set_border_color_all(light_color_1);
+ style_button_type->set_border_color_all(contrast_color_2);
- Ref<StyleBoxFlat> style_button_type_disabled = change_border_color(style_button_type, dark_color_2);
+ Ref<StyleBoxFlat> style_button_type_disabled = change_border_color(style_button_type, contrast_color_1);
- Color button_font_color = light_color_1.linear_interpolate(Color(1, 1, 1, 1), .6);
+ Color button_font_color = contrast_color_1.linear_interpolate(font_color, .6);
// Button
theme->set_stylebox("normal", "Button", style_button_type);
- theme->set_stylebox("hover", "Button", change_border_color(style_button_type, HIGHLIGHT_COLOR_LIGHT));
+ theme->set_stylebox("hover", "Button", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT));
theme->set_stylebox("pressed", "Button", change_border_color(style_button_type, highlight_color));
theme->set_stylebox("focus", "Button", change_border_color(style_button_type, highlight_color));
theme->set_stylebox("disabled", "Button", style_button_type_disabled);
theme->set_color("font_color", "Button", button_font_color);
-
- theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_FONT);
theme->set_color("font_color_pressed", "Button", highlight_color);
- theme->set_color("icon_color_hover", "Button", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_disabled", "Button", font_color_disabled);
+ theme->set_color("icon_color_hover", "Button", HIGHLIGHT_COLOR_FONT);
// make icon color value bigger because icon image is not complete white
theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a));
// OptionButton
Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
style_option_button->set_border_width_all(border_width);
- style_option_button->set_border_color_all(light_color_1);
- theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_LIGHT));
- theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, highlight_color));
+ theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, contrast_color_1));
+ theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT));
theme->set_stylebox("focus", "OptionButton", change_border_color(style_button_type, highlight_color));
theme->set_stylebox("disabled", "OptionButton", style_button_type_disabled);
theme->set_stylebox("normal", "OptionButton", style_button_type);
theme->set_color("font_color", "OptionButton", button_font_color);
- theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT);
theme->set_color("font_color_pressed", "OptionButton", highlight_color);
- theme->set_color("icon_color_hover", "OptionButton", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_disabled", "OptionButton", font_color_disabled);
+ theme->set_color("icon_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT);
theme->set_icon("arrow", "OptionButton", theme->get_icon("GuiOptionArrow", "EditorIcons"));
theme->set_constant("arrow_margin", "OptionButton", 4);
theme->set_constant("modulate_arrow", "OptionButton", true);
@@ -319,24 +386,44 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// CheckButton
theme->set_icon("on", "CheckButton", theme->get_icon("GuiToggleOn", "EditorIcons"));
theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons"));
+ theme->set_color("font_color", "CheckButton", button_font_color);
+ theme->set_color("font_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("font_color_pressed", "CheckButton", highlight_color);
+ theme->set_color("font_color_disabled", "CheckButton", font_color_disabled);
+ theme->set_color("icon_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT);
+
+ // Checkbox
+ theme->set_icon("checked", "CheckBox", theme->get_icon("GuiChecked", "EditorIcons"));
+ theme->set_icon("unchecked", "CheckBox", theme->get_icon("GuiUnchecked", "EditorIcons"));
+ theme->set_icon("radio_checked", "CheckBox", theme->get_icon("GuiRadioChecked", "EditorIcons"));
+ theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon("GuiRadioUnchecked", "EditorIcons"));
+
+ theme->set_color("font_color", "CheckBox", button_font_color);
+ theme->set_color("font_color_hover", "CheckBox", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("font_color_pressed", "CheckBox", highlight_color);
+ theme->set_color("font_color_disabled", "CheckBox", font_color_disabled);
+ theme->set_color("icon_color_hover", "CheckBox", HIGHLIGHT_COLOR_FONT);
// PopupMenu
Ref<StyleBoxFlat> style_popup_menu = make_flat_stylebox(dark_color_1, 8, 8, 8, 8);
style_popup_menu->set_border_width_all(MAX(EDSCALE, border_width));
- style_popup_menu->set_border_color_all(light_color_1);
+ style_popup_menu->set_border_color_all(contrast_color_1);
theme->set_stylebox("panel", "PopupMenu", style_popup_menu);
theme->set_stylebox("separator", "PopupMenu", make_line_stylebox(separator_color, MAX(EDSCALE, border_width), 8 - MAX(EDSCALE, border_width)));
+ theme->set_color("font_color", "PopupMenu", font_color);
+ theme->set_color("font_color_hover", "PopupMenu", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("font_color_accel", "PopupMenu", font_color);
+ theme->set_color("font_color_disabled", "PopupMenu", font_color_disabled);
+ theme->set_icon("checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
+ theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
+ theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
+ theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
// Tree & ItemList background
Ref<StyleBoxFlat> style_tree_bg = make_flat_stylebox(dark_color_1, 2, 4, 2, 4);
style_tree_bg->set_border_width_all(border_width);
style_tree_bg->set_border_color_all(dark_color_3);
theme->set_stylebox("bg", "Tree", style_tree_bg);
- // Script background
- Ref<StyleBoxFlat> style_script_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0);
- style_script_bg->set_border_width_all(border_width);
- style_script_bg->set_border_color_all(dark_color_3);
- theme->set_stylebox("ScriptPanel", "EditorStyles", style_script_bg);
// Tree
theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons"));
@@ -348,21 +435,23 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("custom_button", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_hover", "Tree", style_button_type);
- theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("font_color", "Tree", font_color_disabled);
+ theme->set_color("font_color_selected", "Tree", font_color);
- Ref<StyleBox> style_tree_btn = make_flat_stylebox(light_color_1, 2, 4, 2, 4);
+ Ref<StyleBox> style_tree_btn = make_flat_stylebox(contrast_color_1, 2, 4, 2, 4);
theme->set_stylebox("button_pressed", "Tree", style_tree_btn);
- Ref<StyleBoxFlat> style_tree_focus = make_flat_stylebox(HIGHLIGHT_COLOR_DARK, 2, 2, 2, 2);
+ Ref<StyleBoxFlat> style_tree_focus = make_flat_stylebox(HIGHLIGHT_COLOR_BG, 2, 2, 2, 2);
theme->set_stylebox("selected_focus", "Tree", style_tree_focus);
- Ref<StyleBoxFlat> style_tree_selected = make_flat_stylebox(HIGHLIGHT_COLOR_DARK, 2, 2, 2, 2);
+ Ref<StyleBoxFlat> style_tree_selected = make_flat_stylebox(HIGHLIGHT_COLOR_BG, 2, 2, 2, 2);
theme->set_stylebox("selected", "Tree", style_tree_selected);
- Ref<StyleBoxFlat> style_tree_cursor = make_flat_stylebox(HIGHLIGHT_COLOR_DARK, 4, 4, 4, 4);
- style_tree_cursor->set_filled(false);
+ Ref<StyleBoxFlat> style_tree_cursor = make_flat_stylebox(HIGHLIGHT_COLOR_BG, 4, 4, 4, 4);
+ style_tree_cursor->set_draw_center(false);
style_tree_cursor->set_border_width_all(border_width);
- style_tree_cursor->set_border_color_all(light_color_1);
+ style_tree_cursor->set_border_color_all(contrast_color_1);
Ref<StyleBoxFlat> style_tree_title = make_flat_stylebox(dark_color_3, 4, 4, 4, 4);
theme->set_stylebox("cursor", "Tree", style_tree_cursor);
@@ -371,11 +460,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("title_button_hover", "Tree", style_tree_title);
theme->set_stylebox("title_button_pressed", "Tree", style_tree_title);
- theme->set_color("prop_category", "Editor", dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.12));
- theme->set_color("prop_section", "Editor", dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.09));
- theme->set_color("prop_subsection", "Editor", dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.06));
- theme->set_color("fg_selected", "Editor", HIGHLIGHT_COLOR_DARK);
- theme->set_color("fg_error", "Editor", theme->get_color("error_color", "Editor"));
+ Color prop_category_color = dark_theme ? dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.12) : dark_color_1.linear_interpolate(Color(0, 0, 0, 1), 0.2);
+ Color prop_section_color = dark_theme ? dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.09) : dark_color_1.linear_interpolate(Color(0, 1, 0, 1), 0.1);
+ Color prop_subsection_color = dark_theme ? dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.06) : dark_color_1.linear_interpolate(Color(0, 0, 0, 1), 0.1);
+ theme->set_color("prop_category", "Editor", prop_category_color);
+ theme->set_color("prop_section", "Editor", prop_section_color);
+ theme->set_color("prop_subsection", "Editor", prop_subsection_color);
+ theme->set_color("fg_selected", "Editor", HIGHLIGHT_COLOR_BG);
+ theme->set_color("fg_error", "Editor", error_color);
theme->set_color("drop_position_color", "Tree", highlight_color);
// ItemList
@@ -384,9 +476,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_itemlist_bg->set_border_color_all(dark_color_3);
Ref<StyleBoxFlat> style_itemlist_cursor = make_flat_stylebox(highlight_color, 0, 0, 0, 0);
- style_itemlist_cursor->set_filled(false);
+ style_itemlist_cursor->set_draw_center(false);
style_itemlist_cursor->set_border_width_all(border_width);
- style_itemlist_cursor->set_border_color_all(HIGHLIGHT_COLOR_DARK);
+ style_itemlist_cursor->set_border_color_all(HIGHLIGHT_COLOR_BG);
theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor);
theme->set_stylebox("cursor_unfocused", "ItemList", style_itemlist_cursor);
theme->set_stylebox("selected_focus", "ItemList", style_tree_focus);
@@ -394,21 +486,24 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("bg_focus", "ItemList", focus_sbt);
theme->set_stylebox("bg", "ItemList", style_itemlist_bg);
theme->set_constant("vseparation", "ItemList", 5 * EDSCALE);
+ theme->set_color("font_color", "ItemList", font_color);
- Ref<StyleBoxFlat> style_tab_fg = make_flat_stylebox(title_color_hl, 15, 5, 15, 5);
- Ref<StyleBoxFlat> style_tab_bg = make_flat_stylebox(base_color, 15, 5, 15, 5);
- style_tab_bg->set_filled(false);
+ Ref<StyleBoxFlat> style_tab_fg = make_flat_stylebox(tab_color, 15, 5, 15, 5);
+ Ref<StyleBoxFlat> style_tab_bg = make_flat_stylebox(tab_color, 15, 5, 15, 5);
+ style_tab_bg->set_draw_center(false);
// Tabs & TabContainer
theme->set_stylebox("tab_fg", "TabContainer", style_tab_fg);
theme->set_stylebox("tab_bg", "TabContainer", style_tab_bg);
theme->set_stylebox("tab_fg", "Tabs", style_tab_fg);
theme->set_stylebox("tab_bg", "Tabs", style_tab_bg);
- theme->set_color("font_color_fg", "TabContainer", title_color_hl_text_color);
- theme->set_color("font_color_bg", "TabContainer", light_color_2);
+ theme->set_color("font_color_fg", "TabContainer", font_color);
+ theme->set_color("font_color_bg", "TabContainer", font_color_disabled);
+ theme->set_color("font_color_fg", "Tabs", font_color);
+ theme->set_color("font_color_bg", "Tabs", font_color_disabled);
theme->set_icon("menu", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons"));
theme->set_icon("menu_hl", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons"));
- theme->set_stylebox("SceneTabFG", "EditorStyles", make_flat_stylebox(title_color_hl, 10, 5, 10, 5));
+ theme->set_stylebox("SceneTabFG", "EditorStyles", make_flat_stylebox(base_color, 10, 5, 10, 5));
theme->set_stylebox("SceneTabBG", "EditorStyles", make_empty_stylebox(6, 5, 6, 5));
theme->set_icon("close", "Tabs", theme->get_icon("GuiClose", "EditorIcons"));
theme->set_stylebox("button_pressed", "Tabs", style_menu);
@@ -424,21 +519,23 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Ref<StyleBoxFlat> style_tab_fg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5);
Ref<StyleBoxFlat> style_tab_bg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5);
- style_tab_bg_debugger->set_filled(false);
+ style_tab_bg_debugger->set_draw_center(false);
theme->set_stylebox("DebuggerTabFG", "EditorStyles", style_tab_fg_debugger);
theme->set_stylebox("DebuggerTabBG", "EditorStyles", style_tab_bg_debugger);
// LineEdit
- Ref<StyleBoxFlat> style_lineedit = style_button_type;
- style_lineedit = change_border_color(style_lineedit, light_color_1);
- Ref<StyleBoxFlat> style_lineedit_disabled = change_border_color(style_lineedit, dark_color_1);
- style_lineedit_disabled->set_bg_color(Color(0, 0, 0, .1));
- Ref<StyleBoxFlat> style_lineedit_focus = change_border_color(style_lineedit, highlight_color);
- theme->set_stylebox("normal", "LineEdit", style_lineedit);
- theme->set_stylebox("focus", "LineEdit", style_lineedit_focus);
- theme->set_stylebox("read_only", "LineEdit", style_lineedit_disabled);
- theme->set_color("read_only", "LineEdit", dark_color_1);
+ Ref<StyleBoxFlat> style_line_edit = make_flat_stylebox(dark_color_1, 6, 4, 6, 4);
+ style_line_edit = change_border_color(style_line_edit, contrast_color_1);
+ Ref<StyleBoxFlat> style_line_edit_disabled = change_border_color(style_line_edit, dark_color_1);
+ style_line_edit_disabled->set_bg_color(Color(0, 0, 0, .1));
+ Ref<StyleBoxFlat> style_line_edit_focus = change_border_color(style_line_edit, highlight_color);
+ theme->set_stylebox("normal", "LineEdit", style_line_edit);
+ theme->set_stylebox("focus", "LineEdit", style_line_edit_focus);
+ theme->set_stylebox("read_only", "LineEdit", style_line_edit_disabled);
+ theme->set_color("read_only", "LineEdit", font_color_disabled);
+ theme->set_color("font_color", "LineEdit", font_color);
+ theme->set_color("cursor_color", "LineEdit", font_color);
// TextEdit
Ref<StyleBoxFlat> style_textedit_normal(memnew(StyleBoxFlat));
@@ -464,11 +561,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// WindowDialog
Ref<StyleBoxFlat> style_window = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
style_window->set_border_width_all(MAX(EDSCALE, border_width));
- style_window->set_border_color_all(title_color_hl);
+ style_window->set_border_color_all(base_color);
style_window->set_border_width(MARGIN_TOP, 24 * EDSCALE);
style_window->set_expand_margin_size(MARGIN_TOP, 24 * EDSCALE);
theme->set_stylebox("panel", "WindowDialog", style_window);
- theme->set_color("title_color", "WindowDialog", title_color_hl_text_color);
+ theme->set_color("title_color", "WindowDialog", font_color);
theme->set_icon("close", "WindowDialog", theme->get_icon("GuiClose", "EditorIcons"));
theme->set_icon("close_highlight", "WindowDialog", theme->get_icon("GuiClose", "EditorIcons"));
theme->set_constant("close_h_ofs", "WindowDialog", 22 * EDSCALE);
@@ -512,20 +609,28 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons"));
//RichTextLabel
+ Color rtl_combined_bg_color = dark_color_1.linear_interpolate(script_bg_color, script_bg_color.a);
+ Color rtl_font_color = (rtl_combined_bg_color.r + rtl_combined_bg_color.g + rtl_combined_bg_color.b > 0.5 * 3) ? Color(0, 0, 0) : Color(1, 1, 1);
+ theme->set_color("default_color", "RichTextLabel", rtl_font_color);
theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox());
+ theme->set_stylebox("normal", "RichTextLabel", make_flat_stylebox(script_bg_color, 6, 6, 6, 6));
// Panel
- theme->set_stylebox("panel", "Panel", style_panel);
+ theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4));
+
+ // Label
+ theme->set_color("font_color", "Label", font_color);
// TooltipPanel
Ref<StyleBoxFlat> style_tooltip = make_flat_stylebox(Color(1, 1, 1, 0.8), 8, 8, 8, 8);
style_tooltip->set_border_width_all(border_width);
- style_tooltip->set_border_color_all(Color(1, 1, 1, 0.9));
+ style_tooltip->set_border_color_all(HIGHLIGHT_COLOR_FONT);
+ theme->set_color("font_color", "TooltipPanel", font_color);
theme->set_stylebox("panel", "TooltipPanel", style_tooltip);
// PopupPanel
Ref<StyleBoxFlat> style_dock_select = make_flat_stylebox(base_color);
- style_dock_select->set_border_color_all(light_color_1);
+ style_dock_select->set_border_color_all(contrast_color_1);
style_dock_select->set_expand_margin_size_all(2);
style_dock_select->set_border_width_all(2);
theme->set_stylebox("panel", "PopupPanel", style_dock_select);
@@ -536,14 +641,15 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// ProgressBar
theme->set_stylebox("bg", "ProgressBar", make_stylebox(theme->get_icon("GuiProgressBar", "EditorIcons"), 4, 4, 4, 4, 0, 0, 0, 0));
theme->set_stylebox("fg", "ProgressBar", make_stylebox(theme->get_icon("GuiProgressFill", "EditorIcons"), 6, 6, 6, 6, 2, 1, 2, 1));
-
- // theme->set_font("font", "ProgressBar", default_font);
-
- // theme->set_color("font_color", "ProgressBar", control_font_color_hover);
- theme->set_color("font_color_shadow", "ProgressBar", Color(0, 0, 0));
+ theme->set_color("font_color", "ProgressBar", font_color);
// GraphEdit
theme->set_stylebox("bg", "GraphEdit", make_flat_stylebox(dark_color_2, 4, 4, 4, 4));
+ theme->set_color("grid_major", "GraphEdit", Color(font_color.r, font_color.g, font_color.b, 0.2));
+ theme->set_color("grid_minor", "GraphEdit", Color(font_color_disabled.r, font_color_disabled.g, font_color_disabled.b, 0.2));
+ theme->set_icon("minus", "GraphEdit", theme->get_icon("ZoomLess", "EditorIcons"));
+ theme->set_icon("more", "GraphEdit", theme->get_icon("ZoomMore", "EditorIcons"));
+ theme->set_icon("reset", "GraphEdit", theme->get_icon("ZoomReset", "EditorIcons"));
// GraphNode
Ref<StyleBoxFlat> graphsb = make_flat_stylebox(Color(0, 0, 0, 0.3), 16, 24, 16, 5);
@@ -568,7 +674,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("commentfocus", "GraphNode", graphsbcommentselected);
// FileDialog
- Color disable_color = light_color_2;
+ Color disable_color = contrast_color_2;
disable_color.a = 0.7;
theme->set_color("files_disabled", "FileDialog", disable_color);
diff --git a/editor/export_template_manager.h b/editor/export_template_manager.h
index ce6d8024ae..c77f85688f 100644
--- a/editor/export_template_manager.h
+++ b/editor/export_template_manager.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* export_template_manager.cpp */
+/* export_template_manager.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index d0d8b0f0cd..a66d1724a1 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -199,11 +199,33 @@ void FileSystemDock::_notification(int p_what) {
int new_mode = int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode"));
+ //_update_icons
+
+ button_reload->set_icon(get_icon("Reload", "EditorIcons"));
+ button_favorite->set_icon(get_icon("Favorites", "EditorIcons"));
+ button_back->set_icon(get_icon("Filesystem", "EditorIcons"));
+ if (display_mode == DISPLAY_THUMBNAILS) {
+ button_display_mode->set_icon(get_icon("FileList", "EditorIcons"));
+ } else {
+ button_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons"));
+ }
+
+ search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+
+ button_hist_next->set_icon(get_icon("Forward", "EditorIcons"));
+ button_hist_prev->set_icon(get_icon("Back", "EditorIcons"));
+
+ Theme::get_default()->clear_icon("ResizedFolder", "EditorIcons");
+ Theme::get_default()->clear_icon("ResizedFile", "EditorIcons");
+
if (new_mode != display_mode) {
set_display_mode(new_mode);
} else {
_update_files(true);
}
+
+ _update_tree();
+
} break;
}
}
@@ -367,6 +389,7 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *
fi.name = file;
fi.type = p_path->get_file_type(i);
fi.path = p_path->get_file_path(i);
+ fi.import_broken = !p_path->get_file_import_is_valid(i);
fi.import_status = 0;
matches->push_back(fi);
@@ -401,6 +424,7 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
thumbnail_size *= EDSCALE;
Ref<Texture> folder_thumbnail;
Ref<Texture> file_thumbnail;
+ Ref<Texture> file_thumbnail_broken;
bool use_thumbnails = (display_mode == DISPLAY_THUMBNAILS);
bool use_folders = search_box->get_text().length() == 0 && split_mode;
@@ -434,8 +458,18 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
Theme::get_default()->set_icon("ResizedFile", "EditorIcons", resized_file);
}
+ if (!has_icon("ResizedFileBroken", "EditorIcons")) {
+ Ref<ImageTexture> file = get_icon("FileBigBroken", "EditorIcons");
+ Ref<Image> img = file->get_data();
+ img->resize(thumbnail_size, thumbnail_size);
+ Ref<ImageTexture> resized_file = Ref<ImageTexture>(memnew(ImageTexture));
+ resized_file->create_from_image(img, 0);
+ Theme::get_default()->set_icon("ResizedFileBroken", "EditorIcons", resized_file);
+ }
+
file_thumbnail = get_icon("ResizedFile", "EditorIcons");
+ file_thumbnail_broken = get_icon("ResizedFileBroken", "EditorIcons");
} else {
files->set_icon_mode(ItemList::ICON_MODE_LEFT);
@@ -496,6 +530,7 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
fi.name = efd->get_file(i);
fi.path = path.plus_file(fi.name);
fi.type = efd->get_file_type(i);
+ fi.import_broken = !efd->get_file_import_is_valid(i);
fi.import_status = 0;
filelist.push_back(fi);
@@ -511,24 +546,21 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
StringName type = E->get().type;
Ref<Texture> type_icon;
+ Ref<Texture> big_icon = file_thumbnail;
String tooltip = fname;
- if (E->get().import_status == 0) {
+ if (!E->get().import_broken) {
if (has_icon(type, ei)) {
type_icon = get_icon(type, ei);
} else {
type_icon = get_icon(oi, ei);
}
- } else if (E->get().import_status == 1) {
- type_icon = get_icon("DependencyOk", "EditorIcons");
- } else if (E->get().import_status == 2) {
- type_icon = get_icon("DependencyChanged", "EditorIcons");
- tooltip += TTR("\nStatus: Needs Re-Import");
- } else if (E->get().import_status == 3) {
+ } else {
type_icon = get_icon("ImportFail", "EditorIcons");
- tooltip += ("\nStatus: Missing Dependencies");
+ big_icon = file_thumbnail_broken;
+ tooltip += TTR("\nStatus: Import of file failed. Please fix file and reimport manually.");
}
if (E->get().sources.size()) {
@@ -538,14 +570,16 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
}
if (use_thumbnails) {
- files->add_item(fname, file_thumbnail, true);
+ files->add_item(fname, big_icon, true);
files->set_item_metadata(files->get_item_count() - 1, fp);
files->set_item_tag_icon(files->get_item_count() - 1, type_icon);
Array udata;
udata.resize(2);
udata[0] = files->get_item_count() - 1;
udata[1] = fname;
- EditorResourcePreview::get_singleton()->queue_resource_preview(fp, this, "_thumbnail_done", udata);
+ if (!E->get().import_broken) {
+ EditorResourcePreview::get_singleton()->queue_resource_preview(fp, this, "_thumbnail_done", udata);
+ }
} else {
files->add_item(fname, type_icon, true);
files->set_item_metadata(files->get_item_count() - 1, fp);
@@ -794,7 +828,12 @@ void FileSystemDock::_move_operation(const String &p_to_path) {
//make list of remaps
Map<String, String> renames;
String repfrom = path == "res://" ? path : String(path + "/");
- String repto = p_to_path == "res://" ? p_to_path : String(p_to_path + "/");
+ String repto = p_to_path;
+ if (!repto.ends_with("/")) {
+ repto += "/";
+ }
+
+ print_line("reprfrom: " + repfrom + " repto " + repto);
for (int i = 0; i < move_files.size(); i++) {
renames[move_files[i]] = move_files[i].replace_first(repfrom, repto);
@@ -834,6 +873,13 @@ void FileSystemDock::_move_operation(const String &p_to_path) {
if (err != OK) {
EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + "\n");
}
+ if (FileAccess::exists(move_files[i] + ".import")) { //move imported files too
+ //@todo should remove the files in .import folder
+ err = da->rename(move_files[i] + ".import", to + ".import");
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + ".import\n");
+ }
+ }
}
for (int i = 0; i < move_dirs.size(); i++) {
@@ -1793,7 +1839,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
path = "res://";
- add_constant_override("separation", 3);
+ add_constant_override("separation", 4);
}
FileSystemDock::~FileSystemDock() {
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index c33a745ce4..a35b145085 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -169,6 +169,7 @@ private:
StringName type;
int import_status; //0 not imported, 1 - ok, 2- must reimport, 3- broken
Vector<String> sources;
+ bool import_broken;
bool operator<(const FileInfo &fi) const {
return name < fi.name;
diff --git a/editor/icons/SCsub b/editor/icons/SCsub
index 07fe45ce11..534a8186a5 100644
--- a/editor/icons/SCsub
+++ b/editor/icons/SCsub
@@ -10,42 +10,25 @@ def make_editor_icons_action(target, source, env):
dst = target[0].srcnode().abspath
svg_icons = source
- whites = StringIO()
- darks = StringIO()
+ icons_string = StringIO()
for f in svg_icons:
fname = str(f)
- whites.write('\t"')
- darks.write('\t"')
+ icons_string.write('\t"')
with open(fname, 'rb') as svgf:
b = svgf.read(1)
while(len(b) == 1):
- whites.write("\\" + str(hex(ord(b)))[1:])
+ icons_string.write("\\" + str(hex(ord(b)))[1:])
b = svgf.read(1)
- try:
- with open(os.path.dirname(fname) + "/dark/" + os.path.basename(fname), 'rb') as svgf:
- b = svgf.read(1)
- while(len(b) == 1):
- darks.write("\\" + str(hex(ord(b)))[1:])
- b = svgf.read(1)
- except IOError:
- with open(fname, 'rb') as svgf:
- b = svgf.read(1)
- while(len(b) == 1):
- darks.write("\\" + str(hex(ord(b)))[1:])
- b = svgf.read(1)
- whites.write('"')
- darks.write('"')
+ icons_string.write('"')
if fname != svg_icons[-1]:
- whites.write(",")
- darks.write(",")
- whites.write('\n')
- darks.write('\n')
+ icons_string.write(",")
+ icons_string.write('\n')
s = StringIO()
s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
@@ -53,10 +36,7 @@ def make_editor_icons_action(target, source, env):
s.write("#define _EDITOR_ICONS_H\n")
s.write("static const int editor_icons_count = %s;\n" % len(svg_icons))
s.write("static const char *editor_icons_sources[] = {\n")
- s.write(whites.getvalue())
- s.write('};\n\n')
- s.write("static const char *editor_icons_sources_dark[] = {\n")
- s.write(darks.getvalue())
+ s.write(icons_string.getvalue())
s.write('};\n\n')
s.write("static const char *editor_icons_names[] = {\n")
for f in svg_icons:
@@ -78,8 +58,7 @@ def make_editor_icons_action(target, source, env):
f.write(s.getvalue())
f.close()
s.close()
- whites.close()
- darks.close()
+ icons_string.close()
make_editor_icons_builder = Builder(action=make_editor_icons_action,
suffix='.h',
diff --git a/editor/icons/dark/icon_2_d.svg b/editor/icons/dark/icon_2_d.svg
deleted file mode 100644
index 2f2bfbff8a..0000000000
--- a/editor/icons/dark/icon_2_d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3.9844 1.002a1.0001 1.0001 0 0 0 -0.69141 0.29102l-2 2a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l0.29297-0.29297v8.5859h8.5859l-0.29297 0.29297a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 0 -1.4141l-2-2a1 1 0 0 0 -0.7207 -0.29102 1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l0.29297 0.29297h-6.5859v-6.5859l0.29297 0.29297a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-2-2a1.0001 1.0001 0 0 0 -0.72266 -0.29102z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_3_d.svg b/editor/icons/dark/icon_3_d.svg
deleted file mode 100644
index be55e1d90f..0000000000
--- a/editor/icons/dark/icon_3_d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3.9902 1.002a1.0001 1.0001 0 0 0 -0.69141 0.29102l-2 2a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l0.29297-0.29297v8.5859h8.5859l-0.29297 0.29297a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 0 -1.4141l-2-2a1 1 0 0 0 -0.72266 -0.29102 1 1 0 0 0 -0.69141 0.29102 1 1 0 0 0 0 1.4141l0.29297 0.29297h-5.1719l5.5859-5.5859v0.41602a1 1 0 0 0 1 1 1 1 0 0 0 1 -1v-2.8301a1.0001 1.0001 0 0 0 -1 -1h-2.8301a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h0.41602l-5.5859 5.5859v-5.1719l0.29297 0.29297a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-2-2a1.0001 1.0001 0 0 0 -0.72266 -0.29102z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_checked.svg b/editor/icons/dark/icon_GUI_checked.svg
deleted file mode 100644
index 5ae9a8c57c..0000000000
--- a/editor/icons/dark/icon_GUI_checked.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 2c-1.1046 0-2 0.89543-2 2v8c0 1.1046 0.89543 2 2 2h8c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2h-8zm7.293 2.293l1.4141 1.4141-6.707 6.707-2.707-2.707 1.4141-1.4141 1.293 1.293 5.293-5.293z" fill="#4f4f4f" fill-opacity=".78431"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_dropdown.svg b/editor/icons/dark/icon_GUI_dropdown.svg
deleted file mode 100644
index 9115b5d83f..0000000000
--- a/editor/icons/dark/icon_GUI_dropdown.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#000000" fill-opacity=".58824" stroke-linejoin="round" stroke-opacity=".39216" stroke-width="2">
-<circle cx="7.5" cy="1040.9" r="1.5"/>
-<circle cx="7.5" cy="1045.9" r="1.5"/>
-<circle cx="7.5" cy="1050.9" r="1.5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_hslider_bg.svg b/editor/icons/dark/icon_GUI_hslider_bg.svg
deleted file mode 100644
index e298d06c4c..0000000000
--- a/editor/icons/dark/icon_GUI_hslider_bg.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="1" y="1041.4" width="14" height="6" ry="0" fill-opacity=".39216" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_hsplitter.svg b/editor/icons/dark/icon_GUI_hsplitter.svg
deleted file mode 100644
index 73f3f483d8..0000000000
--- a/editor/icons/dark/icon_GUI_hsplitter.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="64" version="1.1" viewBox="0 0 8 64" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -988.36)">
-<path d="m4 990.36v60" fill="none" stroke="#000000" stroke-linecap="round" stroke-opacity=".39216" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_mini_tab_menu.svg b/editor/icons/dark/icon_GUI_mini_tab_menu.svg
deleted file mode 100644
index 44236ebab9..0000000000
--- a/editor/icons/dark/icon_GUI_mini_tab_menu.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="6" height="16" version="1.1" viewBox="0 0 6 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#000000" fill-opacity=".39216">
-<circle cx="3" cy="1038.4" r="2"/>
-<circle cx="3" cy="1044.4" r="2"/>
-<circle cx="3" cy="1050.4" r="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_option_arrow.svg b/editor/icons/dark/icon_GUI_option_arrow.svg
deleted file mode 100644
index 2942998a8d..0000000000
--- a/editor/icons/dark/icon_GUI_option_arrow.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m10 1043.4c-0.26378 0.01-0.5144 0.1165-0.69726 0.3067l-3.293 3.2929-3.293-3.2929c-0.18826-0.1936-0.44679-0.3028-0.7168-0.3028-0.89742 2e-4 -1.3404 1.0909-0.69727 1.7168l4 4c0.39053 0.3904 1.0235 0.3904 1.4141 0l4-4c0.65734-0.6321 0.19491-1.7422-0.7168-1.7207z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#000000" fill-opacity=".78431" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_play_button_group.svg b/editor/icons/dark/icon_GUI_play_button_group.svg
deleted file mode 100644
index 1d67816b3a..0000000000
--- a/editor/icons/dark/icon_GUI_play_button_group.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="32" height="32" version="1.1" viewBox="0 0 32 31.999998" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1020.4)">
-<circle cx="16" cy="1036.4" r="14" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_progress_bar.svg b/editor/icons/dark/icon_GUI_progress_bar.svg
deleted file mode 100644
index b052cfb50e..0000000000
--- a/editor/icons/dark/icon_GUI_progress_bar.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1036.4c-1.0907-2e-4 -2 0.9073-2 1.998v12.002c0 1.0907 0.9093 2 2 2h12c1.0907 0 2-0.9093 2-2v-12c0-1.0907-0.9093-1.9978-2-1.998zm0 2h12v11.998h-12z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".39216" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_progress_fill.svg b/editor/icons/dark/icon_GUI_progress_fill.svg
deleted file mode 100644
index 91e6722c33..0000000000
--- a/editor/icons/dark/icon_GUI_progress_fill.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="4" y="1040.4" width="8" height="8" ry=".99999" fill="#4f4f4f" fill-opacity=".39216"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_radio_checked.svg b/editor/icons/dark/icon_GUI_radio_checked.svg
deleted file mode 100644
index 5b5fd23a78..0000000000
--- a/editor/icons/dark/icon_GUI_radio_checked.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="8" cy="1044.4" r="5" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".78431" stroke-width="2"/>
-<circle cx="8" cy="1044.4" r="3" fill="#4f4f4f" fill-opacity=".78431"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_radio_unchecked.svg b/editor/icons/dark/icon_GUI_radio_unchecked.svg
deleted file mode 100644
index f3deacc992..0000000000
--- a/editor/icons/dark/icon_GUI_radio_unchecked.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="8" cy="1044.4" r="5" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".78431" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_scroll_bg.svg b/editor/icons/dark/icon_GUI_scroll_bg.svg
deleted file mode 100644
index 302368b19a..0000000000
--- a/editor/icons/dark/icon_GUI_scroll_bg.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 11.999999" xmlns="http://www.w3.org/2000/svg"></svg>
diff --git a/editor/icons/dark/icon_GUI_scroll_grabber.svg b/editor/icons/dark/icon_GUI_scroll_grabber.svg
deleted file mode 100644
index bf1bc19523..0000000000
--- a/editor/icons/dark/icon_GUI_scroll_grabber.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 11.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<circle cx="6" cy="1046.4" r="2" fill="#000000" fill-opacity=".27451"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_scroll_grabber_hl.svg b/editor/icons/dark/icon_GUI_scroll_grabber_hl.svg
deleted file mode 100644
index e165cf3cfb..0000000000
--- a/editor/icons/dark/icon_GUI_scroll_grabber_hl.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 11.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<circle cx="6" cy="1046.4" r="3" fill="#f9f9f9" fill-opacity=".73"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_scroll_grabber_pressed.svg b/editor/icons/dark/icon_GUI_scroll_grabber_pressed.svg
deleted file mode 100644
index 729289e756..0000000000
--- a/editor/icons/dark/icon_GUI_scroll_grabber_pressed.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 11.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<circle cx="6" cy="1046.4" r="3" d="m 8.9999952,1046.3623 c 0,1.6569 -1.3431436,3 -2.9999952,3 -1.6568516,0 -2.9999952,-1.3431 -2.9999952,-3 0,-1.6568 1.3431436,-3 2.9999952,-3 1.6568516,0 2.9999952,1.3432 2.9999952,3 z" fill="#afafaf" fill-opacity=".72941"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_slider_grabber.svg b/editor/icons/dark/icon_GUI_slider_grabber.svg
deleted file mode 100644
index 63332d7da9..0000000000
--- a/editor/icons/dark/icon_GUI_slider_grabber.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="8" cy="1044.4" r="3" fill="#000000" fill-opacity=".78431" stroke-linejoin="round" stroke-opacity=".39216" stroke-width="3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_slider_grabber_hl.svg b/editor/icons/dark/icon_GUI_slider_grabber_hl.svg
deleted file mode 100644
index 5ba266ce06..0000000000
--- a/editor/icons/dark/icon_GUI_slider_grabber_hl.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a5 5 0 0 1 0.5 0.025391 5 5 0 0 1 0.49414 0.074219 5 5 0 0 1 0.48438 0.12305 5 5 0 0 1 0.46875 0.17188 5 5 0 0 1 0.44922 0.2168 5 5 0 0 1 0.42578 0.26172 5 5 0 0 1 0.39844 0.30273 5 5 0 0 1 0.36524 0.33984 5 5 0 0 1 0.33008 0.37695 5 5 0 0 1 0.29102 0.40625 5 5 0 0 1 0.24805 0.43359 5 5 0 0 1 0.20508 0.45508 5 5 0 0 1 0.1582 0.47461 5 5 0 0 1 0.10938 0.48828 5 5 0 0 1 0.060547 0.49609 5 5 0 0 1 0.011719 0.35352 5 5 0 0 1 -0.025391 0.5 5 5 0 0 1 -0.074218 0.49414 5 5 0 0 1 -0.12305 0.48438 5 5 0 0 1 -0.17188 0.46875 5 5 0 0 1 -0.2168 0.44922 5 5 0 0 1 -0.26172 0.42578 5 5 0 0 1 -0.30273 0.39844 5 5 0 0 1 -0.33984 0.36524 5 5 0 0 1 -0.37695 0.33008 5 5 0 0 1 -0.40625 0.29102 5 5 0 0 1 -0.43359 0.24805 5 5 0 0 1 -0.45508 0.20508 5 5 0 0 1 -0.47461 0.1582 5 5 0 0 1 -0.48828 0.10938 5 5 0 0 1 -0.49609 0.060547 5 5 0 0 1 -0.35352 0.011719 5 5 0 0 1 -0.5 -0.025391 5 5 0 0 1 -0.49414 -0.074218 5 5 0 0 1 -0.48438 -0.12305 5 5 0 0 1 -0.46875 -0.17188 5 5 0 0 1 -0.44922 -0.2168 5 5 0 0 1 -0.42578 -0.26172 5 5 0 0 1 -0.39844 -0.30273 5 5 0 0 1 -0.36523 -0.33984 5 5 0 0 1 -0.33008 -0.37695 5 5 0 0 1 -0.29102 -0.40625 5 5 0 0 1 -0.24805 -0.43359 5 5 0 0 1 -0.20508 -0.45508 5 5 0 0 1 -0.1582 -0.47461 5 5 0 0 1 -0.10938 -0.48828 5 5 0 0 1 -0.060547 -0.49609 5 5 0 0 1 -0.011719 -0.35352 5 5 0 0 1 0.025391 -0.5 5 5 0 0 1 0.074219 -0.49414 5 5 0 0 1 0.12305 -0.48438 5 5 0 0 1 0.17188 -0.46875 5 5 0 0 1 0.2168 -0.44922 5 5 0 0 1 0.26172 -0.42578 5 5 0 0 1 0.30273 -0.39844 5 5 0 0 1 0.33984 -0.36523 5 5 0 0 1 0.37695 -0.33008 5 5 0 0 1 0.40625 -0.29102 5 5 0 0 1 0.43359 -0.24805 5 5 0 0 1 0.45508 -0.20508 5 5 0 0 1 0.47461 -0.1582 5 5 0 0 1 0.48828 -0.10938 5 5 0 0 1 0.49609 -0.060547 5 5 0 0 1 0.35352 -0.011719z" fill="#4f4f4f"/>
-<circle cx="8" cy="1044.4" r="3" fill="#000000" fill-opacity=".58824" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_spinbox_updown.svg b/editor/icons/dark/icon_GUI_spinbox_updown.svg
deleted file mode 100644
index 94d2044284..0000000000
--- a/editor/icons/dark/icon_GUI_spinbox_updown.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9844 1.002a1.0001 1.0001 0 0 0 -0.69141 0.29102l-4 4a1.0001 1.0001 0 1 0 1.4141 1.4141l3.293-3.293 3.293 3.293a1.0001 1.0001 0 1 0 1.4141 -1.4141l-4-4a1.0001 1.0001 0 0 0 -0.72266 -0.29102zm4.0059 7.9844a1.0001 1.0001 0 0 0 -0.69726 0.30664l-3.293 3.293-3.293-3.293a1.0001 1.0001 0 0 0 -0.7168 -0.30273 1.0001 1.0001 0 0 0 -0.69727 1.7168l4 4a1.0001 1.0001 0 0 0 1.4141 0l4-4a1.0001 1.0001 0 0 0 -0.7168 -1.7207z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".78431" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_tab_menu.svg b/editor/icons/dark/icon_GUI_tab_menu.svg
deleted file mode 100644
index 7075713425..0000000000
--- a/editor/icons/dark/icon_GUI_tab_menu.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#000000" fill-opacity=".39216">
-<circle cx="8" cy="1038.4" r="2"/>
-<circle cx="8" cy="1044.4" r="2"/>
-<circle cx="8" cy="1050.4" r="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_toggle_off.svg b/editor/icons/dark/icon_GUI_toggle_off.svg
deleted file mode 100644
index bf479e62d7..0000000000
--- a/editor/icons/dark/icon_GUI_toggle_off.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="64" height="32" version="1.1" viewBox="0 0 64 31.999998" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1020.4)">
-<path transform="translate(0 1020.4)" d="m24 4.002c-6.6307 0-12 5.3654-12 11.996v0.003906c0 6.6307 5.3693 12 12 12h16c6.6307 0 12-5.3693 12-12v-0.003906c0-6.6307-5.3693-11.996-12-11.996h-16zm0 2h16c5.5573 0 10 4.4388 10 9.9961v0.003906c0 5.5573-4.4427 10-10 10h-16c-5.5573 0-10-4.4427-10-10v-0.003906c0-5.5573 4.4427-9.9961 10-9.9961zm7 4.9961a1.0001 1.0001 0 0 0 -1 1v8a1 1 0 0 0 1 1 1 1 0 0 0 1 -1v-3h2a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-2v-2h4a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-5zm9 0a1.0001 1.0001 0 0 0 -1 1v4 4a1 1 0 0 0 1 1 1 1 0 0 0 1 -1v-3h2a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-2v-2h4a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-5zm-17 0.003906c-2.7496 0-5 2.2504-5 5s2.2504 5 5 5 5-2.2504 5-5-2.2504-5-5-5zm0 2c1.6687 0 3 1.3313 3 3s-1.3313 3-3 3-3-1.3313-3-3 1.3313-3 3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".78431" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_toggle_on.svg b/editor/icons/dark/icon_GUI_toggle_on.svg
deleted file mode 100644
index b81391c88d..0000000000
--- a/editor/icons/dark/icon_GUI_toggle_on.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="64" height="32" version="1.1" viewBox="0 0 64 31.999998" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1020.4)">
-<path transform="translate(0 1020.4)" d="m24 4.002c-6.6307 0-12 5.3654-12 11.996 0 6.6307 5.3693 12 12 12h16c6.6307 0 12-5.3693 12-12 0-6.6307-5.3693-11.996-12-11.996h-16zm17 6.9961a1 1 0 0 1 1 1v8a1.0001 1.0001 0 0 1 -1.752 0.66211l-5.248-6v5.3379a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-8a1.0001 1.0001 0 0 1 1.752 -0.6582l5.248 6v-5.3418a1 1 0 0 1 1 -1zm-15 0.003906c2.7496 0 5 2.2504 5 5s-2.2504 5-5 5-5-2.2504-5-5 2.2504-5 5-5zm0 2c-1.6687 0-3 1.3313-3 3s1.3313 3 3 3 3-1.3313 3-3-1.3313-3-3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".78431" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_tree_arrow_down.svg b/editor/icons/dark/icon_GUI_tree_arrow_down.svg
deleted file mode 100644
index fc071c84ca..0000000000
--- a/editor/icons/dark/icon_GUI_tree_arrow_down.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m3 1045.4 3 3 3-3" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".39216" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_tree_arrow_right.svg b/editor/icons/dark/icon_GUI_tree_arrow_right.svg
deleted file mode 100644
index ffd84f5774..0000000000
--- a/editor/icons/dark/icon_GUI_tree_arrow_right.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m4 1049.4 3-3-3-3" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".39216" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_unchecked.svg b/editor/icons/dark/icon_GUI_unchecked.svg
deleted file mode 100644
index cbf3bd3dc0..0000000000
--- a/editor/icons/dark/icon_GUI_unchecked.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 2a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2v-8a2 2 0 0 0 -2 -2h-8zm0.80078 2h6.3984a0.8 0.8 0 0 1 0.80078 0.80078v6.3984a0.8 0.8 0 0 1 -0.80078 0.80078h-6.3984a0.8 0.8 0 0 1 -0.80078 -0.80078v-6.3984a0.8 0.8 0 0 1 0.80078 -0.80078z" fill="#4f4f4f" fill-opacity=".78431"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_vslider_bg.svg b/editor/icons/dark/icon_GUI_vslider_bg.svg
deleted file mode 100644
index 99d01420b6..0000000000
--- a/editor/icons/dark/icon_GUI_vslider_bg.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="6" y="1037.4" width="4" height="14" ry="0" fill-opacity=".39216" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_vsplit_bg.svg b/editor/icons/dark/icon_GUI_vsplit_bg.svg
deleted file mode 100644
index 8294c44611..0000000000
--- a/editor/icons/dark/icon_GUI_vsplit_bg.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 7.9999995" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect y="1044.4" width="8" height="8" fill-opacity=".098039"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_GUI_vsplitter.svg b/editor/icons/dark/icon_GUI_vsplitter.svg
deleted file mode 100644
index 002108a24a..0000000000
--- a/editor/icons/dark/icon_GUI_vsplitter.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="64" height="8" version="1.1" viewBox="0 0 64 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path d="m2 1048.4h60" fill="none" stroke="#000000" stroke-linecap="round" stroke-opacity=".39216" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_accept_dialog.svg b/editor/icons/dark/icon_accept_dialog.svg
deleted file mode 100644
index ad33c8e97f..0000000000
--- a/editor/icons/dark/icon_accept_dialog.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.8954-2 2v1h14v-1c0-1.1046-0.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-8zm9.4746 1.6367 1.4141 1.4141-4.9492 4.9492-2.8281-2.8281 1.4141-1.4141 1.4141 1.4141z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_add.svg b/editor/icons/dark/icon_add.svg
deleted file mode 100644
index 762c95df8f..0000000000
--- a/editor/icons/dark/icon_add.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_anchor.svg b/editor/icons/dark/icon_anchor.svg
deleted file mode 100644
index 1c00b027d8..0000000000
--- a/editor/icons/dark/icon_anchor.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8262v0.17383h-2v2h2v3.8984a5 5 0 0 1 -3.8281 -3.6035l-1.9336 0.51758a7 7 0 0 0 6.7617 5.1875 7 7 0 0 0 6.7617 -5.1875l-1.9375-0.51953a5 5 0 0 1 -3.8242 3.6035v-3.8965h2v-2h-2v-0.17578a3 3 0 0 0 2 -2.8242 3 3 0 0 0 -3 -3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_animated_sprite.svg b/editor/icons/dark/icon_animated_sprite.svg
deleted file mode 100644
index a90181fa45..0000000000
--- a/editor/icons/dark/icon_animated_sprite.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff">
-<path transform="translate(0 1036.4)" d="m10.5 0a5.5 5.5 0 0 0 -5.3301 4.1699 5.5 5.5 0 0 1 1.3301 -0.16992 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.16992 1.3301 5.5 5.5 0 0 0 4.1699 -5.3301 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".39216"/>
-<path transform="translate(0 1036.4)" d="m8.5 2a5.5 5.5 0 0 0 -4.7559 2.748 5.5 5.5 0 0 1 2.7559 -0.74805 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.74414 2.752 5.5 5.5 0 0 0 2.7441 -4.752 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".58824"/>
-<path transform="translate(0 1036.4)" d="m6.5 4a5.5 5.5 0 0 0 -5.5 5.5 5.5 5.5 0 0 0 5.5 5.5 5.5 5.5 0 0 0 5.5 -5.5 5.5 5.5 0 0 0 -5.5 -5.5zm-2.5 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-5 3h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_animated_sprite_3d.svg b/editor/icons/dark/icon_animated_sprite_3d.svg
deleted file mode 100644
index 40dad30a7e..0000000000
--- a/editor/icons/dark/icon_animated_sprite_3d.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f">
-<path transform="translate(0 1036.4)" d="m10.5 0a5.5 5.5 0 0 0 -5.3301 4.1699 5.5 5.5 0 0 1 1.3301 -0.16992 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.16992 1.3301 5.5 5.5 0 0 0 4.1699 -5.3301 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".39216"/>
-<path transform="translate(0 1036.4)" d="m8.5 2a5.5 5.5 0 0 0 -4.7559 2.748 5.5 5.5 0 0 1 2.7559 -0.74805 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.74414 2.752 5.5 5.5 0 0 0 2.7441 -4.752 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".58824"/>
-<path transform="translate(0 1036.4)" d="m6.5 4a5.5 5.5 0 0 0 -5.5 5.5 5.5 5.5 0 0 0 5.5 5.5 5.5 5.5 0 0 0 5.5 -5.5 5.5 5.5 0 0 0 -5.5 -5.5zm-2.5 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-5 3h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_animation.svg b/editor/icons/dark/icon_animation.svg
deleted file mode 100644
index 39b7a44d02..0000000000
--- a/editor/icons/dark/icon_animation.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 4 -1.5352v1.5352h0.001953a2 2 0 0 0 0.26562 1 2 2 0 0 0 1.7324 1h1v-1-1h-0.5a0.5 0.49999 0 0 1 -0.5 -0.5v-0.5-5a6 6 0 0 0 -6 -6zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm3.4414 2a1 1 0 0 1 0.88867 0.5 1 1 0 0 1 -0.36523 1.3652 1 1 0 0 1 -1.3672 -0.36523 1 1 0 0 1 0.36719 -1.3652 1 1 0 0 1 0.47656 -0.13477zm-6.9531 0.0019531a1 1 0 0 1 0.54688 0.13281 1 1 0 0 1 0.36719 1.3652 1 1 0 0 1 -1.3672 0.36523 1 1 0 0 1 -0.36523 -1.3652 1 1 0 0 1 0.81836 -0.49805zm0.023438 3.998a1 1 0 0 1 0.89062 0.5 1 1 0 0 1 -0.36719 1.3652 1 1 0 0 1 -1.3652 -0.36523 1 1 0 0 1 0.36523 -1.3652 1 1 0 0 1 0.47656 -0.13477zm6.9043 0.0019531a1 1 0 0 1 0.54883 0.13281 1 1 0 0 1 0.36523 1.3652 1 1 0 0 1 -1.3652 0.36523 1 1 0 0 1 -0.36719 -1.3652 1 1 0 0 1 0.81836 -0.49805zm-3.416 1.998a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_animation_player.svg b/editor/icons/dark/icon_animation_player.svg
deleted file mode 100644
index 4de8694a9b..0000000000
--- a/editor/icons/dark/icon_animation_player.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m1 1037.4v14h1.1667v-2h1.8333v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.8333v-2zm1.1667 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2zm-9.8333 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2z" fill="#bb6dff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_animation_tree_player.svg b/editor/icons/dark/icon_animation_tree_player.svg
deleted file mode 100644
index c475b16127..0000000000
--- a/editor/icons/dark/icon_animation_tree_player.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v14h1.166v-2h1.834v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.834v-2h-1.166zm4 3h2v1 1h1 3v2h-2v1 1h1 1v2h-1-2a1.0001 1.0001 0 0 1 -1 -1v-1-2h-1a1.0001 1.0001 0 0 1 -1 -1v-1-1-1zm-2.834 1h1.834v2h-1.834v-2zm9.834 0h2v2h-2v-2zm-9.834 4h1.834v2h-1.834v-2zm9.834 0h2v2h-2v-2z" fill="#bb6dff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_area.svg b/editor/icons/dark/icon_area.svg
deleted file mode 100644
index ebea4e4008..0000000000
--- a/editor/icons/dark/icon_area.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_area_2d.svg b/editor/icons/dark/icon_area_2d.svg
deleted file mode 100644
index f8d5cddef4..0000000000
--- a/editor/icons/dark/icon_area_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_arrow_left.svg b/editor/icons/dark/icon_arrow_left.svg
deleted file mode 100644
index 12d9360c51..0000000000
--- a/editor/icons/dark/icon_arrow_left.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9863 3.002a1 1 0 0 0 -0.69336 0.29102l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-2.293-2.293h4.5859a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-4.5859l2.293-2.293a1 1 0 0 0 0 -1.4141 1 1 0 0 0 -0.7207 -0.29102z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_arrow_right.svg b/editor/icons/dark/icon_arrow_right.svg
deleted file mode 100644
index ca3b4a0267..0000000000
--- a/editor/icons/dark/icon_arrow_right.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 3.002a1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l2.293 2.293h-4.5859c-0.55228 0-1 0.4477-1 1s0.44772 1 1 1h4.5859l-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l4-4a1.0001 1.0001 0 0 0 0 -1.4141l-4-4a1 1 0 0 0 -0.7207 -0.29102z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_arrow_up.svg b/editor/icons/dark/icon_arrow_up.svg
deleted file mode 100644
index 08e77d2c65..0000000000
--- a/editor/icons/dark/icon_arrow_up.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2.9875 1044.4a1.0001 1.0001 0 0 0 1.7168 0.6972l2.293-2.2929v4.5859a1.0001 1.0001 0 1 0 2 0v-4.5859l2.293 2.2929a1.0001 1.0001 0 1 0 1.4141 -1.414l-3.9141-3.9141a1.0001 1.0001 0 0 0 -1.5859 0 1.0001 1.0001 0 0 0 -0.00391 0.01l-3.9102 3.9102a1.0001 1.0001 0 0 0 -0.30273 0.7168z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_asset_lib.svg b/editor/icons/dark/icon_asset_lib.svg
deleted file mode 100644
index b9ef0db316..0000000000
--- a/editor/icons/dark/icon_asset_lib.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1c-1.6569 0-3 1.3431-3 3v2h-4v7c0 1.108 0.89199 2 2 2h10c1.108 0 2-0.89199 2-2v-7h-4v-2c0-1.6569-1.3431-3-3-3zm0 2c0.55228 0 1 0.44772 1 1v2h-2v-2c0-0.55228 0.44772-1 1-1z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_atlas_texture.svg b/editor/icons/dark/icon_atlas_texture.svg
deleted file mode 100644
index 1d2de12446..0000000000
--- a/editor/icons/dark/icon_atlas_texture.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m6 1037.4-5 2v12l5-2 4 2 5-2v-12l-5 2zm0 2 4 2v8l-4-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_bus_bypass.svg b/editor/icons/dark/icon_audio_bus_bypass.svg
deleted file mode 100644
index d683928e27..0000000000
--- a/editor/icons/dark/icon_audio_bus_bypass.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6.9707 2c-0.25474 0.01-0.49715 0.11122-0.67773 0.29102l-2.707 2.707h-1.5859c-0.55226 1e-4 -0.99994 0.4477-1 1v4c5.52e-5 0.5523 0.44774 0.9999 1 1h1.5859l2.707 2.707c0.63002 0.6296 1.7067 0.18367 1.707-0.70703v-10c-9.424e-4 -0.5631-0.46642-1.0144-1.0293-0.99805zm3.0293 5v1 1h4v-1-1h-4z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_bus_layout.svg b/editor/icons/dark/icon_audio_bus_layout.svg
deleted file mode 100644
index c6fa4b21ee..0000000000
--- a/editor/icons/dark/icon_audio_bus_layout.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="1" y2="15" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.108 0-2 0.89199-2 2v10c0 1.108 0.89199 2 2 2h2c1.108 0 2-0.89199 2-2v-10c0-1.108-0.89199-2-2-2h-2zm8 0c-1.108 0-2 0.89199-2 2v10c0 1.108 0.89199 2 2 2h2c1.108 0 2-0.89199 2-2v-10c0-1.108-0.89199-2-2-2h-2zm-8 1h2c0.55401 0 1 0.44599 1 1v10c0 0.55401-0.44599 1-1 1h-2c-0.55401 0-1-0.44599-1-1v-10c0-0.55401 0.44599-1 1-1z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_bus_mute.svg b/editor/icons/dark/icon_audio_bus_mute.svg
deleted file mode 100644
index 3f8f0888cc..0000000000
--- a/editor/icons/dark/icon_audio_bus_mute.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6.9707 2c-0.25474 0.01-0.49715 0.11122-0.67773 0.29102l-2.707 2.707h-1.5859c-0.55226 1e-4 -0.99994 0.4477-1 1v4c5.52e-5 0.5523 0.44774 0.9999 1 1h1.5859l2.707 2.707c0.63002 0.6296 1.7067 0.18367 1.707-0.70703v-10c-9.424e-4 -0.5631-0.46642-1.0144-1.0293-0.99805zm4.0195 2.9902a1.0001 1.0001 0 0 0 -0.69726 1.7168l1.293 1.293-1.293 1.293a1.0001 1.0001 0 1 0 1.4141 1.4141l1.293-1.293 1.293 1.293a1.0001 1.0001 0 1 0 1.4141 -1.4141l-1.293-1.293 1.293-1.293a1.0001 1.0001 0 0 0 -0.72656 -1.7148 1.0001 1.0001 0 0 0 -0.6875 0.30078l-1.293 1.293-1.293-1.293a1.0001 1.0001 0 0 0 -0.7168 -0.30273z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_bus_solo.svg b/editor/icons/dark/icon_audio_bus_solo.svg
deleted file mode 100644
index c4a3f16c04..0000000000
--- a/editor/icons/dark/icon_audio_bus_solo.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6.9707 2c-0.25474 0.01-0.49715 0.11122-0.67773 0.29102l-2.707 2.707h-1.5859c-0.55226 1e-4 -0.99994 0.4477-1 1v4c5.52e-5 0.5523 0.44774 0.9999 1 1h1.5859l2.707 2.707c0.63002 0.6296 1.7067 0.18367 1.707-0.70703v-10c-9.424e-4 -0.5631-0.46642-1.0144-1.0293-0.99805zm8.0293 2a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3 -3v-2a1 1 0 0 1 1 -1h1v-2h-1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_effect_amplify.svg b/editor/icons/dark/icon_audio_effect_amplify.svg
deleted file mode 100644
index 3a37ae26fd..0000000000
--- a/editor/icons/dark/icon_audio_effect_amplify.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="9" x2="9" y1="1037.4" y2="1051.4" gradientTransform="translate(0 -1036.4)" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m15 1-14 7h14zm-13 9v1h2v-1zm2 1v1h-2v-1h-1v4h1v-2h2v2h1v-4zm2-1v5h1v-4h1v4h1v-4h1v-1zm4 1v4h1v-4zm2-1v5h1v-2h2v-3zm1 1h1v1h-1z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_stream_gibberish.svg b/editor/icons/dark/icon_audio_stream_gibberish.svg
deleted file mode 100644
index 69704c1bbc..0000000000
--- a/editor/icons/dark/icon_audio_stream_gibberish.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 2a2 2 0 0 0 -2 2v5a2 2 0 0 0 2 2h3v3l3-3h4a2 2 0 0 0 2 -2v-5a2 2 0 0 0 -2 -2h-10zm0 4h2v1h-2v-1zm5 0a1 1 0 0 1 1 1v1a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-1a1 1 0 0 1 1 -1zm3 0h2v1h-2v-1z" fill="#4f4f4f" fill-opacity=".99216"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_stream_player.svg b/editor/icons/dark/icon_audio_stream_player.svg
deleted file mode 100644
index 76fb1d8308..0000000000
--- a/editor/icons/dark/icon_audio_stream_player.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="1" y2="15" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)" shape-rendering="auto">
-<path d="m10.023 1044.4c-0.56139-0.013-1.0235 0.4264-1.0234 0.9724v5.0542c6.911e-4 0.7482 0.83361 1.2154 1.5 0.8414l4-2.5262c0.66694-0.3743 0.66694-1.3104 0-1.6847l-4-2.5261c-0.14505-0.082-0.30893-0.1269-0.47656-0.131z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" image-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-<path transform="translate(0 1036.4)" d="m11.971 1.002a1.0001 1.0001 0 0 0 -0.24609 0.037109l-7 2a1.0001 1.0001 0 0 0 -0.72461 0.96094v5.5508a2.5 2.5 0 0 0 -0.5 -0.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961 -2.4121 1.0001 1.0001 0 0 0 0.0039062 -0.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293 -0.99805z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" image-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_stream_player_2_d.svg b/editor/icons/dark/icon_audio_stream_player_2_d.svg
deleted file mode 100644
index 09b137d901..0000000000
--- a/editor/icons/dark/icon_audio_stream_player_2_d.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="1" y2="15" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)" shape-rendering="auto">
-<path d="m10.023 1044.4c-0.56139-0.013-1.0235 0.4264-1.0234 0.9724v5.0542c6.911e-4 0.7482 0.83361 1.2154 1.5 0.8414l4-2.5262c0.66694-0.3743 0.66694-1.3104 0-1.6847l-4-2.5261c-0.14505-0.082-0.30893-0.1269-0.47656-0.131z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#6d90ff" image-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-<path transform="translate(0 1036.4)" d="m11.971 1.002a1.0001 1.0001 0 0 0 -0.24609 0.037109l-7 2a1.0001 1.0001 0 0 0 -0.72461 0.96094v5.5508a2.5 2.5 0 0 0 -0.5 -0.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961 -2.4121 1.0001 1.0001 0 0 0 0.0039062 -0.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293 -0.99805z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" image-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_stream_player_3_d.svg b/editor/icons/dark/icon_audio_stream_player_3_d.svg
deleted file mode 100644
index aa2da200da..0000000000
--- a/editor/icons/dark/icon_audio_stream_player_3_d.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="1" y2="15" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)" shape-rendering="auto">
-<path d="m10.023 1044.4c-0.56139-0.013-1.0235 0.4264-1.0234 0.9724v5.0542c6.911e-4 0.7482 0.83361 1.2154 1.5 0.8414l4-2.5262c0.66694-0.3743 0.66694-1.3104 0-1.6847l-4-2.5261c-0.14505-0.082-0.30893-0.1269-0.47656-0.131z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff5f5f" image-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-<path transform="translate(0 1036.4)" d="m11.971 1.002a1.0001 1.0001 0 0 0 -0.24609 0.037109l-7 2a1.0001 1.0001 0 0 0 -0.72461 0.96094v5.5508a2.5 2.5 0 0 0 -0.5 -0.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961 -2.4121 1.0001 1.0001 0 0 0 0.0039062 -0.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293 -0.99805z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" image-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_audio_stream_sample.svg b/editor/icons/dark/icon_audio_stream_sample.svg
deleted file mode 100644
index 7d99e5405e..0000000000
--- a/editor/icons/dark/icon_audio_stream_sample.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="1" y2="15" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m11.971 1.002c-0.08326 0.00207-0.16593 0.014541-0.24609 0.037109l-7 2c-0.42881 0.12287-0.7244 0.51487-0.72461 0.96094v5.5508c-0.16454-0.033679-0.33205-0.050692-0.5-0.050781-1.3807 0-2.5 1.1193-2.5 2.5-4.75e-6 1.3807 1.1193 2.5 2.5 2.5 1.3456-0.0013 2.4488-1.0674 2.4961-2.4121 0.0025906-0.029226 0.003894-0.058551 0.0039062-0.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-9.16e-4 -0.56314-0.4664-1.0145-1.0293-0.99805zm-1.4707 6.998c-0.277 0-0.5 0.223-0.5 0.5v5c0 0.277 0.223 0.5 0.5 0.5s0.5-0.223 0.5-0.5v-5c0-0.277-0.223-0.5-0.5-0.5zm2 1c-0.277 0-0.5 0.223-0.5 0.5v3c0 0.277 0.223 0.5 0.5 0.5s0.5-0.223 0.5-0.5v-3c0-0.277-0.223-0.5-0.5-0.5zm-4 1c-0.277 0-0.5 0.223-0.5 0.5v1c0 0.277 0.223 0.5 0.5 0.5s0.5-0.223 0.5-0.5v-1c0-0.277-0.223-0.5-0.5-0.5zm6 0c-0.277 0-0.5 0.223-0.5 0.5v1c0 0.277 0.223 0.5 0.5 0.5s0.5-0.223 0.5-0.5v-1c0-0.277-0.223-0.5-0.5-0.5z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_auto_play.svg b/editor/icons/dark/icon_auto_play.svg
deleted file mode 100644
index 1842a2784c..0000000000
--- a/editor/icons/dark/icon_auto_play.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 2a1.0001 1.0001 0 0 0 -1 1v10a1.0001 1.0001 0 0 0 1 1h8a1.0001 1.0001 0 0 0 0.78125 -0.375l4-5a1.0001 1.0001 0 0 0 0 -1.248l-4-5a1.0001 1.0001 0 0 0 -0.78125 -0.37695h-8zm1 2h6.5195l3.1992 4-3.1992 4h-6.5195v-8zm3 1c-1.1046 0-2 0.8954-2 2v4h1v-2h2v2h1v-4c0-1.1046-0.89543-2-2-2zm0 1a1 1 0 0 1 1 1v1h-2v-1a1 1 0 0 1 1 -1zm3 0v4l2-2-2-2z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_back.svg b/editor/icons/dark/icon_back.svg
deleted file mode 100644
index b28962f321..0000000000
--- a/editor/icons/dark/icon_back.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="16" version="1.1" viewBox="0 0 8 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m6 1038.4-4 6 4 6" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_back_buffer_copy.svg b/editor/icons/dark/icon_back_buffer_copy.svg
deleted file mode 100644
index 601c1446df..0000000000
--- a/editor/icons/dark/icon_back_buffer_copy.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v11h5v-2h-3v-7h6v-2zm6 3v11h8v-11zm2 2h4v7h-4z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bake.svg b/editor/icons/dark/icon_bake.svg
deleted file mode 100644
index ec1cbc66ae..0000000000
--- a/editor/icons/dark/icon_bake.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_baked_light.svg b/editor/icons/dark/icon_baked_light.svg
deleted file mode 100644
index d6c6bbf903..0000000000
--- a/editor/icons/dark/icon_baked_light.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_baked_light_instance.svg b/editor/icons/dark/icon_baked_light_instance.svg
deleted file mode 100644
index d6c6bbf903..0000000000
--- a/editor/icons/dark/icon_baked_light_instance.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_baked_light_sampler.svg b/editor/icons/dark/icon_baked_light_sampler.svg
deleted file mode 100644
index a2db34b648..0000000000
--- a/editor/icons/dark/icon_baked_light_sampler.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h4v-2h-4v-6h4 6 2v-3h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-6 3v1h1v-1h-1zm4 1a1 1 0 0 0 -1 1v4a1 1 0 0 0 1 1h4a1 1 0 0 0 1 -1v-4a1 1 0 0 0 -1 -1h-4zm3 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bit_map.svg b/editor/icons/dark/icon_bit_map.svg
deleted file mode 100644
index beed73c550..0000000000
--- a/editor/icons/dark/icon_bit_map.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2h2v-2h-2zm2 2v2h2v-2h-2zm2 0h2v-2h-2v2zm2 0v2h2v-2h-2zm2 0h2v-2h-2v2zm2 0v2h2v-2h-2zm2 0h2v-2h-2v2zm0 2v2h2v-2h-2zm0 2h-2v2h2v-2zm0 2v2h2v-2h-2zm0 2h-2v2h2v-2zm0 2v2h2v-2h-2zm-2 0h-2v2h2v-2zm-2 0v-2h-2v2h2zm-2 0h-2v2h2v-2zm-2 0v-2h-2v2h2zm-2 0h-2v2h2v-2zm0-2v-2h-2v2h2zm0-2h2v-2h-2v2zm0-2v-2h-2v2h2zm2 0h2v-2h-2v2zm2 0v2h2v-2h-2zm2 0h2v-2h-2v2zm0 2v2h2v-2h-2zm-2 0h-2v2h2v-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bitmap_font.svg b/editor/icons/dark/icon_bitmap_font.svg
deleted file mode 100644
index 8d38bf7699..0000000000
--- a/editor/icons/dark/icon_bitmap_font.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m1 1037.4v4h1v-1h1v-1h4v10h-1v1h-1v1h6v-1h-1v-1h-1v-10h4v1h1v1h1v-4z" fill="#5caeff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_blend.svg b/editor/icons/dark/icon_blend.svg
deleted file mode 100644
index 9e9b7259ed..0000000000
--- a/editor/icons/dark/icon_blend.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m9 1v2h2.5859l-3.5859 3.5859-4.293-4.293-1.4141 1.4141 4.293 4.293-4.293 4.293 1.4141 1.4141 4.293-4.293 3.5859 3.5859h-2.5859v2h5a1.0001 1.0001 0 0 0 1 -1v-5h-2v2.5859l-3.5859-3.5859 3.5859-3.5859v2.5859h2v-5a1.0001 1.0001 0 0 0 -1 -1h-5z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bone.svg b/editor/icons/dark/icon_bone.svg
deleted file mode 100644
index 43deb5fc4a..0000000000
--- a/editor/icons/dark/icon_bone.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804 0.7205 2.4664 2.4663 0 0 0 -0.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023 0.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397 0.6955 2.4664 2.4663 0 0 0 0.69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 0.31408 -3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004 -0.3102 2.4664 2.4663 0 0 0 0 -3.4875 2.4664 2.4663 0 0 0 -1.397 -0.6974 2.4664 2.4663 0 0 0 -0.69561 -1.3971 2.4664 2.4663 0 0 0 -1.7072 -0.7205z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bone_attachment.svg b/editor/icons/dark/icon_bone_attachment.svg
deleted file mode 100644
index 7209cf603b..0000000000
--- a/editor/icons/dark/icon_bone_attachment.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804 0.7205 2.4664 2.4663 0 0 0 -0.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023 0.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397 0.6955 2.4664 2.4663 0 0 0 0.69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 0.31408 -3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004 -0.3102 2.4664 2.4663 0 0 0 0 -3.4875 2.4664 2.4663 0 0 0 -1.397 -0.6974 2.4664 2.4663 0 0 0 -0.69561 -1.3971 2.4664 2.4663 0 0 0 -1.7072 -0.7205z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bone_track.svg b/editor/icons/dark/icon_bone_track.svg
deleted file mode 100644
index 850826ea5e..0000000000
--- a/editor/icons/dark/icon_bone_track.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804 0.7205 2.4664 2.4663 0 0 0 -0.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023 0.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397 0.6955 2.4664 2.4663 0 0 0 0.69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 0.31408 -3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004 -0.3102 2.4664 2.4663 0 0 0 0 -3.4875 2.4664 2.4663 0 0 0 -1.397 -0.6974 2.4664 2.4663 0 0 0 -0.69561 -1.3971 2.4664 2.4663 0 0 0 -1.7072 -0.7205z" fill="#bb6dff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bool.svg b/editor/icons/dark/icon_bool.svg
deleted file mode 100644
index 56fcba5833..0000000000
--- a/editor/icons/dark/icon_bool.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m0 4v4 4h2a3 3 0 0 0 2.5 -1.3457 3 3 0 0 0 2.5 1.3457 3 3 0 0 0 2 -0.76758 3 3 0 0 0 2 0.76758 3 3 0 0 0 2.5 -1.3457 3 3 0 0 0 2.5 1.3457v-2a1 1 0 0 1 -1 -1v-5h-2v2.7695a3 3 0 0 0 -2 -0.76953 3 3 0 0 0 -2 0.76758 3 3 0 0 0 -2 -0.76758 3 3 0 0 0 -2.5 1.3457 3 3 0 0 0 -2.5 -1.3457v-2h-2zm2 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v-2zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#cf68ea"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_box_shape.svg b/editor/icons/dark/icon_box_shape.svg
deleted file mode 100644
index b11edb16ca..0000000000
--- a/editor/icons/dark/icon_box_shape.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m8 1l-7 3v8l7 3 7-3v-8l-7-3z" fill="#2998ff"/>
-<path d="m8 1051.4-7-3v-8l7 3z" fill="#68b6ff"/>
-<path d="m1 1040.4 7 3 7-3-7-3z" fill="#a2d2ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bus_vu_db.svg b/editor/icons/dark/icon_bus_vu_db.svg
deleted file mode 100644
index 83163a2c28..0000000000
--- a/editor/icons/dark/icon_bus_vu_db.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="32" height="128" version="1.1" viewBox="0 0 32 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="16" x2="16" y2="128" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m1.5 0c-0.831 0-1.5 0.669-1.5 1.5 0 0.831 0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5 0-0.831-0.669-1.5-1.5-1.5h-2zm0 7c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm22.5 3.75c-1.5 0-3 1.3056-3 3.25-0.01912 1.3523 2.0191 1.3523 2 0 0-1.0556 0.5-1.25 1-1.25s1 0.19444 1 1.25c0 0.59157-0.35893 1.156-1.1914 1.8633-0.83248 0.70724-2.0616 1.4518-3.3574 2.3008-0.82974 0.54516-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.01912 1.3523-2.0191 0-2h-1.7852c0.28375-0.20667 0.63106-0.39443 0.88867-0.61328 1.0302-0.87519 1.8965-1.9783 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm-7.0293 0.25195c-0.14519 0.0037-0.28782 0.03907-0.41797 0.10352l-2 1c-1.1924 0.59646-0.29787 2.3855 0.89453 1.7891l0.55273-0.27539v5.3809c-0.01913 1.3523 2.0191 1.3523 2 0v-7c-9.16e-4 -0.56314-0.4664-1.0145-1.0293-0.99805zm-15.471 2.998c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm0 7c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm21.5 3c-0.554 0-1 0.446-1 1v1 2h-0.92969c-0.02343-8.24e-4 -0.046882-8.24e-4 -0.070312 0-1.0702 0-2.0626 0.57318-2.5977 1.5-0.5351 0.92681-0.5351 2.0732 0 3 0.5351 0.92681 1.5275 1.5 2.5977 1.5h2c0.554 0 1-0.446 1-1v-8c0-0.554-0.446-1-1-1zm4 0c-0.554 0-1 0.446-1 1v8c0 0.554 0.446 1 1 1h2c1.0702 0 2.0626-0.57319 2.5977-1.5 0.5351-0.92682 0.5351-2.0732 0-3-0.10504-0.18193-0.23173-0.34698-0.36914-0.5 0.1378-0.15331 0.26385-0.31764 0.36914-0.5 0.5351-0.92682 0.5351-2.0732 0-3-0.5351-0.92682-1.5275-1.5-2.5977-1.5h-2zm-14 1c-1.6447 0-3 1.3553-3 3v3c0 1.6447 1.3553 3 3 3s3-1.3553 3-3v-3c0-1.6447-1.3553-3-3-3zm15 1h1c0.35887 0 0.6858 0.18921 0.86523 0.5 0.17944 0.31079 0.17944 0.68921 0 1-0.17943 0.31079-0.50636 0.5-0.86523 0.5h-0.070312-0.92969v-2zm-15 1c0.5713 0 1 0.4287 1 1v3c0 0.5713-0.4287 1-1 1s-1-0.4287-1-1v-3c0-0.5713 0.4287-1 1-1zm-11.5 1c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm19.5 2h1v2h-0.92969c-0.02343-8.24e-4 -0.046882-8.24e-4 -0.070312 0-0.35887 0-0.6858-0.18921-0.86523-0.5-0.17944-0.31079-0.17944-0.68921 0-1 0.17943-0.31079 0.50636-0.5 0.86523-0.5zm7 0h1c0.35887 0 0.6858 0.18921 0.86523 0.5 0.17944 0.31079 0.17944 0.68921 0 1-0.17943 0.31079-0.50636 0.5-0.86523 0.5h-1v-2zm-26.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm22.5 2.75c-1.5 0-3 1.3056-3 3.25-0.01912 1.3523 2.0191 1.3523 2 0 0-1.0556 0.5-1.25 1-1.25s1 0.19444 1 1.25c0 0.59157-0.35893 1.156-1.1914 1.8633-0.83248 0.70724-2.0616 1.4518-3.3574 2.3008-0.82974 0.54516-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.01913 1.3523-2.0191 0-2h-1.7852c0.28375-0.20667 0.63106-0.39443 0.88867-0.61328 1.0302-0.87519 1.8965-1.9783 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm-7.0293 0.25195c-0.14519 0.0037-0.28782 0.03907-0.41797 0.10352l-2 1c-1.1924 0.59646-0.29787 2.3855 0.89453 1.7891l0.55273-0.27539v5.3809c-0.01913 1.3523 2.0191 1.3523 2 0v-7c-9.16e-4 -0.56314-0.4664-1.0145-1.0293-0.99805zm-15.471 3.998c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 1v2h3v-2h-3zm-7 6c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm15.986 3.75c-1.5 0-3 1.3056-3 3.25-0.01913 1.3523 2.0191 1.3523 2 0 0-1.0556 0.5-1.25 1-1.25s1 0.19444 1 1.25c0 0.59157-0.35893 1.156-1.1914 1.8633s-2.0616 1.4518-3.3574 2.3008c-0.82974 0.54516-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.01913 1.3523-2.0191 0-2h-1.7871c0.2841-0.20689 0.63273-0.39419 0.89062-0.61328 1.0302-0.87519 1.8965-1.9783 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm7.0469 0.23828c-0.36561-0.0093-0.70715 0.18167-0.89062 0.49805l-3 5c-0.39877 0.66633 0.080888 1.5131 0.85742 1.5137h3v1c-0.01912 1.3523 2.0191 1.3523 2 0v-2c-5.5e-5 -0.55226-0.44774-0.99994-1-1h-2.2324l2.0898-3.4844c0.40768-0.65656-0.05163-1.5077-0.82422-1.5273zm-23.533 3.0117c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm-7.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm24.547 4.9961c-0.12355-0.0037-0.24673 0.01547-0.36328 0.05664 0 0-0.98349 0.3331-1.8906 1.2402-0.90714 0.90717-1.793 2.457-1.793 4.707-6.13e-4 0.07218 0.006604 0.14421 0.021484 0.21484 0.11389 1.5445 1.4072 2.7852 2.9785 2.7852 1.645 0 3-1.355 3-3 0-1.645-1.355-3-3-3-0.01533 0-0.029642 0.003706-0.044922 0.003906 0.084-0.10099 0.16695-0.21188 0.25195-0.29688 0.59286-0.59287 1.1094-0.75781 1.1094-0.75781 1.0726-0.33926 0.85487-1.9171-0.26953-1.9531zm-9.0605 0.005859c-1.0407 0.006928-2.0405 0.55674-2.584 1.498a1 1 0 0 0 0.36523 1.3672 1 1 0 0 0 1.3672 -0.36719c0.24596-0.42602 0.74477-0.6077 1.207-0.43945 0.46226 0.16824 0.728 0.62882 0.64258 1.1133-0.085422 0.48445-0.49245 0.82617-0.98438 0.82617a1 1 0 0 0 -1 1 1 1 0 0 0 1 1c0.49193 0 0.89896 0.34368 0.98438 0.82812 0.085422 0.48446-0.18032 0.94508-0.64258 1.1133-0.46226 0.1683-0.96107-0.015436-1.207-0.44141-0.27644-0.47871-0.88884-0.6423-1.3672-0.36523-0.47752 0.27639-0.64095 0.88733-0.36523 1.3652 0.72462 1.2553 2.2612 1.816 3.623 1.3203 1.3618-0.4956 2.1813-1.9126 1.9297-3.3398-0.1003-0.56884-0.37254-1.0676-0.74023-1.4746 0.37098-0.40777 0.63937-0.91234 0.74023-1.4844 0.25166-1.4272-0.56786-2.8442-1.9297-3.3398-0.34046-0.12392-0.69218-0.182-1.0391-0.17969zm-15.486 1.998c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm16 1c0.56413 0 1 0.43587 1 1s-0.43587 1-1 1-1-0.43587-1-1 0.43587-1 1-1zm-23.5 4c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm16.533 3.9883c-0.36561-0.0093-0.70715 0.18167-0.89062 0.49805l-3 5c-0.39877 0.66633 0.080888 1.5131 0.85742 1.5137h3v1c-0.01912 1.3523 2.0191 1.3523 2 0v-2c-5.5e-5 -0.55226-0.44774-0.99994-1-1h-2.2324l2.0898-3.4844c0.40768-0.65656-0.05163-1.5077-0.82422-1.5273zm6.9668 0.011719c-1.645 0-3 1.355-3 3 0 0.769 0.30369 1.4666 0.78711 2-0.48282 0.53332-0.78711 1.2315-0.78711 2 0 1.645 1.355 3 3 3s3-1.355 3-3c0-0.76846-0.30429-1.4667-0.78711-2 0.48342-0.53345 0.78711-1.231 0.78711-2 0-1.645-1.355-3-3-3zm0 2c0.56413 0 1 0.4359 1 1 0 0.5642-0.43587 1-1 1s-1-0.4358-1-1c0-0.5641 0.43587-1 1-1zm-23.5 1c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm16 1c0.56413 0 1 0.4359 1 1 0 0.5642-0.43587 1-1 1s-1-0.4358-1-1c0-0.5641 0.43587-1 1-1zm-23.5 4c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm16.447 3.9824c-0.08995 0.0063-0.17865 0.024647-0.26367 0.054687 0 0-0.98349 0.33509-1.8906 1.2422-0.90714 0.9068-1.793 2.457-1.793 4.707-6.13e-4 0.0722 0.006604 0.14421 0.021484 0.21484 0.11389 1.5445 1.4072 2.7852 2.9785 2.7852 1.645 0 3-1.355 3-3 0-1.6451-1.355-3-3-3-0.01533 0-0.029642 0.003706-0.044922 0.003906 0.084-0.10099 0.16695-0.21187 0.25195-0.29688 0.59286-0.5929 1.1094-0.75781 1.1094-0.75781 1.0726-0.33926 0.85487-1.9171-0.26953-1.9531-0.03318-0.0017-0.066429-0.0017-0.099609 0zm7.0527 0.017578c-1.6447 0-3 1.3553-3 3v3c0 1.6447 1.3553 3 3 3s3-1.3553 3-3v-3c0-1.6447-1.3553-3-3-3zm0 2c0.5713 0 1 0.4287 1 1v3c0 0.5713-0.4287 1-1 1s-1-0.4287-1-1v-3c0-0.5713 0.4287-1 1-1zm-23.5 1c-0.831 0-1.5 0.669-1.5 1.5 0 0.831 0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5 0-0.831-0.669-1.5-1.5-1.5h-2zm15.5 1.9863c0.56413 0 1 0.4358 1 1 0 0.5641-0.43587 1-1 1s-1-0.4359-1-1c0-0.5642 0.43587-1 1-1zm-8 0.013672v2h3v-2h-3zm-7.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm22.5 3.75c-1.5 0-3 1.3056-3 3.25-0.01912 1.3523 2.0191 1.3523 2 0 0-1.0555 0.5-1.25 1-1.25s1 0.1945 1 1.25c0 0.5916-0.35893 1.1561-1.1914 1.8633-0.83248 0.7072-2.0616 1.4518-3.3574 2.3008-0.82975 0.54515-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.0191 1.3523-2.0191 0-2h-1.7852c0.28375-0.2066 0.63106-0.39438 0.88867-0.61328 1.0302-0.8751 1.8965-1.9782 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm-10 0.25c-1.3523-0.0191-1.3523 2.0191 0 2h3.3828l-3.2773 6.5527c-0.59596 1.1926 1.1931 2.0871 1.7891 0.89454l4-8c0.33239-0.66495-0.15113-1.4472-0.89453-1.4473h-5zm-12.5 3c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm-7.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bus_vu_empty.svg b/editor/icons/dark/icon_bus_vu_empty.svg
deleted file mode 100644
index 15d8274461..0000000000
--- a/editor/icons/dark/icon_bus_vu_empty.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="128" version="1.1" viewBox="0 0 16 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="2" y2="126" gradientTransform="translate(0 924.36)" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -924.36)">
-<path d="m3 926.36c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 5c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1z" fill="url(#a)"/>
-<path transform="translate(0 924.36)" d="m3 2c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 5c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bus_vu_frozen.svg b/editor/icons/dark/icon_bus_vu_frozen.svg
deleted file mode 100644
index 99884d33fc..0000000000
--- a/editor/icons/dark/icon_bus_vu_frozen.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="128" version="1.1" viewBox="0 0 16 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="2" y2="126" gradientUnits="userSpaceOnUse">
-<stop stop-color="#62aeff" offset="0"/>
-<stop stop-color="#75d1e6" offset=".5"/>
-<stop stop-color="#84ffee" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m3 2c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 5c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10z" fill="url(#a)" opacity=".7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_bus_vu_full.svg b/editor/icons/dark/icon_bus_vu_full.svg
deleted file mode 100644
index 1187841d71..0000000000
--- a/editor/icons/dark/icon_bus_vu_full.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="128" version="1.1" viewBox="0 0 16 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="2" y2="126" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff4040" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#00f010" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m3 2c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 5c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10zm0 3c-0.554 0-1 0.446-1 1s0.446 1 1 1h10c0.554 0 1-0.446 1-1s-0.446-1-1-1h-10z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_button.svg b/editor/icons/dark/icon_button.svg
deleted file mode 100644
index 078f47b396..0000000000
--- a/editor/icons/dark/icon_button.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2a1.0001 1.0001 0 0 0 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328h-2zm-1.5 8c-0.831 0-1.5 0.669-1.5 1.5v1.5h-2v2h12v-2h-2v-1.5c0-0.831-0.669-1.5-1.5-1.5h-5z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_button_group.svg b/editor/icons/dark/icon_button_group.svg
deleted file mode 100644
index ceb9d3ada8..0000000000
--- a/editor/icons/dark/icon_button_group.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 1c-0.554 0-1 0.446-1 1v12c0 0.554 0.446 1 1 1h8c0.554 0 1-0.446 1-1v-12c0-0.554-0.446-1-1-1h-8zm1 1h2c0.554 0 1 0.446 1 1s-0.446 1-1 1h-2c-0.554 0-1-0.446-1-1s0.446-1 1-1zm6 0c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1-1-0.44772-1-1 0.44772-1 1-1zm-5 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm5 0c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1-1-0.44772-1-1 0.44772-1 1-1zm0 4c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1-1-0.44772-1-1 0.44772-1 1-1zm-7 2h1v2h-1v-2zm2 0h1v2h-1v-2zm2 0h1v2h-1v-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_camera.svg b/editor/icons/dark/icon_camera.svg
deleted file mode 100644
index ee80e38cf2..0000000000
--- a/editor/icons/dark/icon_camera.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117 -0.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1 -2.2305 3 3 0 0 0 -3 -3z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_camera_2d.svg b/editor/icons/dark/icon_camera_2d.svg
deleted file mode 100644
index 978f5b8964..0000000000
--- a/editor/icons/dark/icon_camera_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117 -0.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1 -2.2305 3 3 0 0 0 -3 -3z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_canvas_item.svg b/editor/icons/dark/icon_canvas_item.svg
deleted file mode 100644
index a8c9910867..0000000000
--- a/editor/icons/dark/icon_canvas_item.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2.9208 1046.4c-0.26373 0.3-0.4204 0.7296-0.4204 1.2383 0 1.6277-3.1381-0.1781-0.33757 2.6703 0.88382 0.899 2.6544 0.6701 3.5382-0.2288 0.88384-0.899 0.88382-2.3565 0-3.2554-1.1002-1.1191-2.2001-1.0845-2.7803-0.4244zm2.3802-1.6103 2.4005 2.4416 6.8014-6.9177c0.66286-0.6742 0.66286-1.7673 0-2.4415-0.66288-0.6741-1.7376-0.6741-2.4005 0z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_canvas_item_material.svg b/editor/icons/dark/icon_canvas_item_material.svg
deleted file mode 100644
index 821d882471..0000000000
--- a/editor/icons/dark/icon_canvas_item_material.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3.1035 3a7 7 0 0 0 -1.418 2h12.631a7 7 0 0 0 -1.4277 -2h-9.7852z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m1.6855 5a7 7 0 0 0 -0.60547 2h13.842a7 7 0 0 0 -0.60547 -2h-12.631z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1.0801 7a7 7 0 0 0 -0.080078 1 7 7 0 0 0 0.078125 1h13.842a7 7 0 0 0 0.080078 -1 7 7 0 0 0 -0.078125 -1h-13.842z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1.0781 9a7 7 0 0 0 0.60547 2h12.631a7 7 0 0 0 0.60547 -2h-13.842z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m3.1113 13a7 7 0 0 0 4.8887 2 7 7 0 0 0 4.8965 -2h-9.7852z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m1.6836 11a7 7 0 0 0 1.4277 2h9.7852a7 7 0 0 0 1.418 -2h-12.631z" fill="#702aff"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -4.8965 2h9.7852a7 7 0 0 0 -4.8887 -2z" fill="#ff2929"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_canvas_item_shader.svg b/editor/icons/dark/icon_canvas_item_shader.svg
deleted file mode 100644
index f1dbc569f4..0000000000
--- a/editor/icons/dark/icon_canvas_item_shader.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m13.303 1c-0.4344 0-0.86973 0.16881-1.2012 0.50586l-1.4688 1.4941h4.3418c0.082839-0.52789-0.072596-1.0872-0.47266-1.4941-0.33144-0.33705-0.76482-0.50586-1.1992-0.50586z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m10.633 3l-1.9668 2h4.8008l1.0352-1.0527c0.2628-0.2673 0.41824-0.60049 0.47266-0.94727h-4.3418z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m8.666 5l-1.9648 2h4.7988l1.9668-2h-4.8008z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m6.7012 7l-1.4004 1.4238 0.56641 0.57617h3.668l1.9648-2h-4.7988z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m5.8672 9l1.834 1.8652 1.834-1.8652h-3.668zm-1.752 0.57812c-0.48501-0.048725-0.90521 0.12503-1.1953 0.45508-0.21472 0.24426-0.35243 0.57797-0.39844 0.9668h3.5625c-0.10223-0.1935-0.22224-0.37965-0.38281-0.54297-0.55011-0.55955-1.1009-0.83018-1.5859-0.87891z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m1.3242 13c0.18414 0.24071 0.43707 0.53374 0.83789 0.94141 0.88382 0.899 2.6552 0.67038 3.5391-0.22852 0.20747-0.21103 0.36064-0.45476 0.4707-0.71289h-4.8477z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m2.5215 11c-0.0105 0.088737-0.021484 0.17696-0.021484 0.27148 0 1.3947-2.2782 0.28739-1.1758 1.7285h4.8477c0.27363-0.64173 0.24047-1.3785-0.087891-2h-3.5625z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_canvas_item_shader_graph.svg b/editor/icons/dark/icon_canvas_item_shader_graph.svg
deleted file mode 100644
index 015765c775..0000000000
--- a/editor/icons/dark/icon_canvas_item_shader_graph.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<defs>
-<clipPath id="a">
-<path d="m8.0625 1025.9a3.375 3 0 0 0 -3.375 3 3.375 3 0 0 0 1.6875 2.5957v9.8115a3.375 3 0 0 0 -1.6875 2.5928 3.375 3 0 0 0 3.375 3 3.375 3 0 0 0 3.375 -3 3.375 3 0 0 0 -1.6875 -2.5957v-8.7832l11.931 10.605a3.375 3 0 0 0 -0.11865 0.7735 3.375 3 0 0 0 3.375 3 3.375 3 0 0 0 3.375 -3 3.375 3 0 0 0 -3.375 -3 3.375 3 0 0 0 -0.87341 0.1025l-11.928-10.602h9.8844a3.375 3 0 0 0 2.9169 1.5 3.375 3 0 0 0 3.375 -3 3.375 3 0 0 0 -3.375 -3 3.375 3 0 0 0 -2.9202 1.5h-11.038a3.375 3 0 0 0 -2.9169 -1.5z" fill="#000000"/>
-</clipPath>
-</defs>
-<g transform="translate(0 -1036.4)">
-<g transform="matrix(.59259 0 0 .66667 -1.7778 353.45)" clip-path="url(#a)">
-<rect x="3" y="1025.9" width="27" height="3" fil#ff2929070"/>
-<rect x="3" y="1028.9" width="27" height="3" fil#ffe337b70"/>
-<rect x="3" y="1031.9" width="27" height="3" fil#74ff34f70"/>
-<rect x="3" y="1034.9" width="27" height="3" fil#2cff98fb9"/>
-<rect x="3" y="1037.9" width="27" height="3" fil#22ccffeff"/>
-<rect x="3" y="1043.9" width="27" height="3" fil#ff27810ac"/>
-<rect x="3" y="1040.9" width="27" height="3" fil#702aff0ff"/>
-</g>
-<ellipse cx="3" cy="1039.4" r="2" fill="#6e6e6e"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_canvas_layer.svg b/editor/icons/dark/icon_canvas_layer.svg
deleted file mode 100644
index 6a12976100..0000000000
--- a/editor/icons/dark/icon_canvas_layer.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2v6h1v-6a1 1 0 0 1 1 -1h6v-1h-6zm10.303 0c-0.4344 0-0.86973 0.16881-1.2012 0.50586l-6.8008 6.918 2.4004 2.4414 6.8008-6.918c0.66286-0.6742 0.66286-1.7672 0-2.4414-0.33144-0.33705-0.76482-0.50586-1.1992-0.50586zm0.69727 6v6a1 1 0 0 1 -1 1h-6v1h6a2 2 0 0 0 2 -2v-6h-1zm-9.8848 2.5781c-0.48501-0.048725-0.90521 0.12503-1.1953 0.45508-0.26373 0.3-0.41992 0.72958-0.41992 1.2383 0 1.6277-3.1385-0.17848-0.33789 2.6699 0.88382 0.899 2.6552 0.67038 3.5391-0.22852 0.88384-0.899 0.88382-2.357 0-3.2559-0.55011-0.55955-1.1009-0.83018-1.5859-0.87891z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_canvas_modulate.svg b/editor/icons/dark/icon_canvas_modulate.svg
deleted file mode 100644
index 997992ef85..0000000000
--- a/editor/icons/dark/icon_canvas_modulate.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m1 1037.4v14h14v-14zm2 2h10v10h-10z" fill="#6d90ff"/>
-<path d="m12 1048.4h-5l5-5z" fill="#70bfff" fill-rule="evenodd"/>
-<path d="m4 1040.4h5l-5 5z" fill="#ff2929" fill-rule="evenodd"/>
-<path d="m4 1048.4v-3l5-5h3v3l-5 5z" fill="#7aff70" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_capsule_mesh.svg b/editor/icons/dark/icon_capsule_mesh.svg
deleted file mode 100644
index 512a307b9c..0000000000
--- a/editor/icons/dark/icon_capsule_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8 1037.4c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922 2.7527 0 5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903zm-1.0059 2.1264v4.8576c-0.66556-0.1047-1.2973-0.372-1.9941-0.6618v-1.3222c0-1.3474 0.79838-2.4648 1.9941-2.8736zm2.0118 0c1.1957 0.4088 1.9941 1.5262 1.9941 2.8736v1.3451c-0.68406 0.3054-1.3142 0.5732-1.9941 0.6663zm-4.0059 6.334c0.67836 0.2231 1.3126 0.447 1.9941 0.5264v2.8848c-1.1957-0.4092-1.9941-1.5242-1.9941-2.8716zm6 0.03v0.5094c0 1.3474-0.79838 2.4619-1.9941 2.8711v-2.8711c0.68606-0.068 1.3207-0.2828 1.9941-0.5094z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fea900" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_capsule_shape.svg b/editor/icons/dark/icon_capsule_shape.svg
deleted file mode 100644
index 2940816d60..0000000000
--- a/editor/icons/dark/icon_capsule_shape.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8 1037.4c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922 2.7527 0 5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#68b6ff" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-<circle cx="6.5" cy="1040.9" r="1.5" fill="#a2d2ff" stroke-width="0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_capsule_shape_2d.svg b/editor/icons/dark/icon_capsule_shape_2d.svg
deleted file mode 100644
index 3549a289e0..0000000000
--- a/editor/icons/dark/icon_capsule_shape_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1c-2.77 0-5 2.23-5 5v4c0 2.77 2.23 5 5 5s5-2.23 5-5v-4c0-2.77-2.23-5-5-5zm0 2c1.662 0 3 1.338 3 3v4c0 1.662-1.338 3-3 3s-3-1.338-3-3v-4c0-1.662 1.338-3 3-3z" fill="#68b6ff" stroke-width="0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_center_container.svg b/editor/icons/dark/icon_center_container.svg
deleted file mode 100644
index 6c847f1db9..0000000000
--- a/editor/icons/dark/icon_center_container.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v10h-10v-10zm3 1l2 2 2-2h-4zm-2 2v4l2-2-2-2zm8 0l-2 2 2 2v-4zm-4 4l-2 2h4l-2-2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_check_box.svg b/editor/icons/dark/icon_check_box.svg
deleted file mode 100644
index 0b7bbdb8a6..0000000000
--- a/editor/icons/dark/icon_check_box.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 2c-1.1046 0-2 0.89543-2 2v9c0 1.1046 0.89543 2 2 2h9c1.1046 0 2-0.89543 2-2v-4.9277l-2 2v2.9277h-9v-9h6.5859l2-2zm9.3633 2.0508-4.9492 4.9492-1.4141-1.4141-1.4141 1.4141 2.8281 2.8281 6.3633-6.3633z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_check_button.svg b/editor/icons/dark/icon_check_button.svg
deleted file mode 100644
index c49beca262..0000000000
--- a/editor/icons/dark/icon_check_button.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 4a4 4 0 0 0 -4 4 4 4 0 0 0 4 4h6a4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4h-6zm0 2h2.541a4 4 0 0 0 -0.54102 2 4 4 0 0 0 0.54102 2h-2.541a2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_checkerboard.svg b/editor/icons/dark/icon_checkerboard.svg
deleted file mode 100644
index dcb8adb2d7..0000000000
--- a/editor/icons/dark/icon_checkerboard.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -988.36)" fill="#000000" stroke-linecap="round" stroke-linejoin="round">
-<rect y="988.36" width="64" height="64" fill-opacity=".19608" stroke-width="2"/>
-<path transform="translate(0 988.36)" d="m0 0v16h16v-16h-16zm16 16v16h16v-16h-16zm16 0h16v-16h-16v16zm16 0v16h16v-16h-16zm0 16h-16v16h16v-16zm0 16v16h16v-16h-16zm-16 0h-16v16h16v-16zm-16 0v-16h-16v16h16z" fill-opacity=".39216" stroke-width="8"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_circle_shape_2d.svg b/editor/icons/dark/icon_circle_shape_2d.svg
deleted file mode 100644
index bfe5aec81a..0000000000
--- a/editor/icons/dark/icon_circle_shape_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8 1038.4a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6z" fill="none" stroke="#68b6ff" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_class_list.svg b/editor/icons/dark/icon_class_list.svg
deleted file mode 100644
index 84c80faded..0000000000
--- a/editor/icons/dark/icon_class_list.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="1" y="1038.4" width="5" height=".99998"/>
-<rect x="6" y="1037.4" width="6" height="3"/>
-<rect x="3" y="1038.4" width="1" height="11"/>
-<rect x="4" y="1043.4" width="5" height="1"/>
-<rect x="9" y="1042.4" width="6" height="3"/>
-<rect x="4" y="1048.4" width="5" height="1"/>
-<rect x="9" y="1047.4" width="6" height="3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_close.svg b/editor/icons/dark/icon_close.svg
deleted file mode 100644
index 351bdc5547..0000000000
--- a/editor/icons/dark/icon_close.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3.7578 2.3438l-1.4141 1.4141 4.2422 4.2422-4.2422 4.2422 1.4141 1.4141 4.2422-4.2422 4.2422 4.2422 1.4141-1.4141-4.2422-4.2422 4.2422-4.2422-1.4141-1.4141-4.2422 4.2422-4.2422-4.2422z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_collapse.svg b/editor/icons/dark/icon_collapse.svg
deleted file mode 100644
index 7c9be68c44..0000000000
--- a/editor/icons/dark/icon_collapse.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1040.4v3.9375l6 5.0625 6-5.0625v-3.9375h-12z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_collision_2d.svg b/editor/icons/dark/icon_collision_2d.svg
deleted file mode 100644
index a1e6d9fbef..0000000000
--- a/editor/icons/dark/icon_collision_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#6d90ff" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_collision_polygon.svg b/editor/icons/dark/icon_collision_polygon.svg
deleted file mode 100644
index 7b46cf030e..0000000000
--- a/editor/icons/dark/icon_collision_polygon.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#ff5f5f" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_collision_shape.svg b/editor/icons/dark/icon_collision_shape.svg
deleted file mode 100644
index 340b182cf5..0000000000
--- a/editor/icons/dark/icon_collision_shape.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="translate(0 1.1802e-5)" stroke="#ff5f5f" stroke-opacity=".99608">
-<path d="m8 1050.4-6-3v-6l6-3 6 3v6z" fill="none" stroke="#ff5f5f" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_collision_shape_2d.svg b/editor/icons/dark/icon_collision_shape_2d.svg
deleted file mode 100644
index 5e672ab1a8..0000000000
--- a/editor/icons/dark/icon_collision_shape_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m14 1050.4h-12v-12h12z" fill="none" stroke="#6d90ff" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_color.svg b/editor/icons/dark/icon_color.svg
deleted file mode 100644
index 4a6b354849..0000000000
--- a/editor/icons/dark/icon_color.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<defs>
-<clipPath id="a">
-<path d="m8 1037.4a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 3a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" fill="#000000"/>
-</clipPath>
-</defs>
-<g transform="translate(0 -1036.4)">
-<circle cx="8" cy="1044.4" r="8" fil#000000fff"/>
-<g clip-path="url(#a)">
-<path d="m6.1883 1037.6a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#f00"/>
-<path transform="matrix(.86603 .5 -.5 .86603 0 0)" d="m527.3 893.68a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#ff4d00"/>
-<path transform="matrix(.5 .86603 -.86603 .5 0 0)" d="m906.63 508.49a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#f90"/>
-<path transform="rotate(90)" d="m1042.6-14.761a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#ffca00"/>
-<path transform="matrix(-.5 .86603 -.86603 -.5 0 0)" d="m898.63-535.87a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#ff0"/>
-<path transform="matrix(-.86603 .5 -.5 -.86603 0 0)" d="m513.44-915.21a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#9fff00"/>
-<path transform="scale(-1)" d="m-9.8118-1051.1a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#0f0"/>
-<path transform="matrix(-.86603 -.5 .5 -.86603 0 0)" d="m-530.92-907.21a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#0fa"/>
-<path transform="matrix(-.5 -.86603 .86603 -.5 0 0)" d="m-910.26-522.01a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#00f"/>
-<path transform="rotate(-90)" d="m-1046.2 1.2385a7 7 0 0 1 3.6235 1e-7l-1.8118 6.7615z" fill="#9000ff"/>
-<path transform="matrix(.5 -.86603 .86603 .5 0 0)" d="m-902.26 522.35a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#f0e"/>
-<path transform="matrix(.86603 -.5 .5 .86603 0 0)" d="m-517.06 901.68a7 7 0 0 1 3.6235 0l-1.8117 6.7615z" fill="#ff009a"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_color_pick.svg b/editor/icons/dark/icon_color_pick.svg
deleted file mode 100644
index e2a9f30853..0000000000
--- a/editor/icons/dark/icon_color_pick.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211l1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_color_picker.svg b/editor/icons/dark/icon_color_picker.svg
deleted file mode 100644
index 775678e644..0000000000
--- a/editor/icons/dark/icon_color_picker.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211l1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_color_picker_button.svg b/editor/icons/dark/icon_color_picker_button.svg
deleted file mode 100644
index 3b0643ef4c..0000000000
--- a/editor/icons/dark/icon_color_picker_button.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211 1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#29d739"/>
-<path transform="translate(0 1036.4)" d="m1 3v6.3438l4.9492-4.9512-1.3926-1.3926h-3.5566zm14 6.4863l-1.5137 1.5137h-0.92969l-0.94922-0.94922-2.9492 2.9492h6.3418v-3.5137z" fill="#29d739"/>
-<path transform="translate(0 1036.4)" d="m10.658 11l-2 2h6.3418v-2h-1.5137-0.92969-1.8984z" fill-opacity=".078431"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_color_ramp.svg b/editor/icons/dark/icon_color_ramp.svg
deleted file mode 100644
index d05355d8c7..0000000000
--- a/editor/icons/dark/icon_color_ramp.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="4" x2="30" y1="14" y2="14" gradientTransform="matrix(.51852 0 0 .7 -.55556 1034.6)" gradientUnits="userSpaceOnUse">
-<stop stop-color="#afff68" offset="0"/>
-<stop stop-color="#ff6b6b" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)">
-<path d="m1 1051.4h14v-14z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_color_rect.svg b/editor/icons/dark/icon_color_rect.svg
deleted file mode 100644
index ca913c123e..0000000000
--- a/editor/icons/dark/icon_color_rect.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="1" y="1037.4" width="2" height="14" fill="#29d739"/>
-<rect x="1" y="1049.4" width="14" height="2" fill="#29d739"/>
-<rect x="1" y="1037.4" width="14" height="2" fill="#29d739"/>
-<rect x="13" y="1037.4" width="2" height="14" fill="#29d739"/>
-<path d="m12 1048.4h-4.8l4.8-4.8z" fill="#70bfff" fill-rule="evenodd"/>
-<path d="m4 1040.4h4.8l-4.8 4.8z" fill="#ff2929" fill-rule="evenodd"/>
-<path d="m4 1048.4v-3.2l4.8-4.8h3.2v3.2l-4.8 4.8z" fill="#7aff70" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_concave_polygon_shape.svg b/editor/icons/dark/icon_concave_polygon_shape.svg
deleted file mode 100644
index 0df696f8b7..0000000000
--- a/editor/icons/dark/icon_concave_polygon_shape.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m8 1l-7 3v8l7 3 7-3v-8l-7-3z" fill="#2998ff"/>
-<path d="m8 1037.4-7 3v8l7 3 7-3v-8l-7-3z" fill="#2998ff"/>
-<path d="m3 1041.4v6l5 2 5-2v-6l-5-2z" fill="#2998ff"/>
-<path d="m8 1049.4 5-2-5-2-5 2z" fill="#a2d2ff"/>
-<path d="m8 1045.4 5 2v-6l-5-2z" fill="#68b6ff"/>
-<path transform="translate(0 1036.4)" d="m8 1-7 3 2 1 5-2 5 2 2-1z" fill="#a2d2ff"/>
-<path transform="translate(0 1036.4)" d="m1 4v8l7 3v-2l-5-2v-6z" fill="#68b6ff"/>
-<path transform="translate(0 1036.4)" d="m15 4-2 1v6l-5 2v2l7-3z" fill="#2998ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_concave_polygon_shape_2d.svg b/editor/icons/dark/icon_concave_polygon_shape_2d.svg
deleted file mode 100644
index 3264e69ffc..0000000000
--- a/editor/icons/dark/icon_concave_polygon_shape_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m14 1050.4h-12v-12l6 6 6-6z" fill="none" stroke="#68b6ff" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_cone_twist_joint.svg b/editor/icons/dark/icon_cone_twist_joint.svg
deleted file mode 100644
index 1ec0abb830..0000000000
--- a/editor/icons/dark/icon_cone_twist_joint.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#ff5f5f" stroke-linecap="round" stroke-width="2">
-<path transform="translate(0 1036.4)" d="m8 2l-6 9a6 3 0 0 0 3 2.5977 6 3 0 0 0 6 0 6 3 0 0 0 3 -2.5977l-6-9z" stroke-linejoin="round"/>
-<ellipse cx="8" cy="1047.4" rx="6" ry="3" stroke-linejoin="round"/>
-<path d="m8 1039.4v8"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_confirmation_dialog.svg b/editor/icons/dark/icon_confirmation_dialog.svg
deleted file mode 100644
index 0520d3101f..0000000000
--- a/editor/icons/dark/icon_confirmation_dialog.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.8954-2 2v1h14v-1c0-1.1046-0.89543-2-2-2h-10zm9 1h1v1h-1v-1zm-11 3v8c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-8h-14zm6.9863 1.002c0.34689-0.0022844 0.6986 0.055762 1.0391 0.17969 1.3618 0.4956 2.1813 1.9126 1.9297 3.3398-0.19105 1.0835-0.96172 1.9461-1.9551 2.3008v0.17773h-1-1v-0.8418a1.0001 1.0001 0 0 1 1 -1.1582c0.49193 0 0.89895-0.34177 0.98438-0.82617 0.085424-0.4845-0.18031-0.94508-0.64258-1.1133-0.46227-0.1683-0.96106 0.013453-1.207 0.43945a1.0002 1.0002 0 0 1 -1.7324 -1c0.54346-0.94148 1.5433-1.4912 2.584-1.498zm-0.98633 6.998h2v1h-2v-1z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_connect.svg b/editor/icons/dark/icon_connect.svg
deleted file mode 100644
index 1c96a195f0..0000000000
--- a/editor/icons/dark/icon_connect.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="4" cy="1048.4" r="2" fill="#4f4f4f"/>
-<path d="m4 1043.4a5 5 0 0 1 5 5" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m4 1039.4a9 9 0 0 1 9 9" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_connection_and_groups.svg b/editor/icons/dark/icon_connection_and_groups.svg
deleted file mode 100644
index 2ae14d9bdd..0000000000
--- a/editor/icons/dark/icon_connection_and_groups.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 0v1 5 1h12v-1-6h-11-1zm1 1h10v5h-10v-5zm2.5 1a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm5 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm-0.5 7a2 2 0 0 0 -2 2v1h-6v1h6v1a2 2 0 0 0 2 2h2v-1h2v-1h-2v-3h2v-1h-2v-1h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_container.svg b/editor/icons/dark/icon_container.svg
deleted file mode 100644
index 07382b3bf7..0000000000
--- a/editor/icons/dark/icon_container.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2h2v-2zm2 0v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h2c0-1.1046-0.89543-2-2-2zm-12 4v2h2v-2h-2zm12 0v2h2v-2h-2zm-12 4v2h2v-2h-2zm12 0v2h2v-2h-2zm-12 4c0 1.1046 0.89543 2 2 2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2c1.1046 0 2-0.89543 2-2h-2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control.svg b/editor/icons/dark/icon_control.svg
deleted file mode 100644
index 94518d5d75..0000000000
--- a/editor/icons/dark/icon_control.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_bottom_center.svg b/editor/icons/dark/icon_control_align_bottom_center.svg
deleted file mode 100644
index 9d1219078e..0000000000
--- a/editor/icons/dark/icon_control_align_bottom_center.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="6" y="1046.4" width="4" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_bottom_left.svg b/editor/icons/dark/icon_control_align_bottom_left.svg
deleted file mode 100644
index fc8e7adb3e..0000000000
--- a/editor/icons/dark/icon_control_align_bottom_left.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1046.4" width="4" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_bottom_right.svg b/editor/icons/dark/icon_control_align_bottom_right.svg
deleted file mode 100644
index 9a9bc0f2ec..0000000000
--- a/editor/icons/dark/icon_control_align_bottom_right.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="10" y="1046.4" width="4" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_bottom_wide.svg b/editor/icons/dark/icon_control_align_bottom_wide.svg
deleted file mode 100644
index 111ea52be7..0000000000
--- a/editor/icons/dark/icon_control_align_bottom_wide.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1046.4" width="12" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_center.svg b/editor/icons/dark/icon_control_align_center.svg
deleted file mode 100644
index 5dd012c389..0000000000
--- a/editor/icons/dark/icon_control_align_center.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="6" y="1042.4" width="4" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_center_left.svg b/editor/icons/dark/icon_control_align_center_left.svg
deleted file mode 100644
index 38542419cf..0000000000
--- a/editor/icons/dark/icon_control_align_center_left.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="2" y="1042.4" width="6" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_center_right.svg b/editor/icons/dark/icon_control_align_center_right.svg
deleted file mode 100644
index 371436a6ad..0000000000
--- a/editor/icons/dark/icon_control_align_center_right.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="8" y="1042.4" width="6" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_left_center.svg b/editor/icons/dark/icon_control_align_left_center.svg
deleted file mode 100644
index dbf11be914..0000000000
--- a/editor/icons/dark/icon_control_align_left_center.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1042.4" width="4" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_left_wide.svg b/editor/icons/dark/icon_control_align_left_wide.svg
deleted file mode 100644
index 7020a8a406..0000000000
--- a/editor/icons/dark/icon_control_align_left_wide.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1038.4" width="4" height="12" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_right_center.svg b/editor/icons/dark/icon_control_align_right_center.svg
deleted file mode 100644
index 2ce0ebdf30..0000000000
--- a/editor/icons/dark/icon_control_align_right_center.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="10" y="1042.4" width="4" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_right_wide.svg b/editor/icons/dark/icon_control_align_right_wide.svg
deleted file mode 100644
index 0c1713cfe8..0000000000
--- a/editor/icons/dark/icon_control_align_right_wide.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="10" y="1038.4" width="4" height="12" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_top_center.svg b/editor/icons/dark/icon_control_align_top_center.svg
deleted file mode 100644
index 4b13ab28b9..0000000000
--- a/editor/icons/dark/icon_control_align_top_center.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="6" y="1038.4" width="4" height="3.9999" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_top_left.svg b/editor/icons/dark/icon_control_align_top_left.svg
deleted file mode 100644
index cd06aaad82..0000000000
--- a/editor/icons/dark/icon_control_align_top_left.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1038.4" width="4" height="3.9999" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_top_right.svg b/editor/icons/dark/icon_control_align_top_right.svg
deleted file mode 100644
index 3bbbb89eca..0000000000
--- a/editor/icons/dark/icon_control_align_top_right.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="10" y="1038.4" width="4" height="3.9999" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_top_wide.svg b/editor/icons/dark/icon_control_align_top_wide.svg
deleted file mode 100644
index d704d5cc81..0000000000
--- a/editor/icons/dark/icon_control_align_top_wide.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1038.4" width="12" height="3.9999" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_align_wide.svg b/editor/icons/dark/icon_control_align_wide.svg
deleted file mode 100644
index 683504128c..0000000000
--- a/editor/icons/dark/icon_control_align_wide.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_hcenter_wide.svg b/editor/icons/dark/icon_control_hcenter_wide.svg
deleted file mode 100644
index c96ba7ca11..0000000000
--- a/editor/icons/dark/icon_control_hcenter_wide.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect x="2" y="1042.4" width="12" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_control_vcenter_wide.svg b/editor/icons/dark/icon_control_vcenter_wide.svg
deleted file mode 100644
index 892bfcc50d..0000000000
--- a/editor/icons/dark/icon_control_vcenter_wide.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#919191"/>
-<rect x="2" y="1038.4" width="12" height="12" fill="#474747"/>
-<rect transform="rotate(90)" x="1038.4" y="-10" width="12" height="4" fill="#d6d6d6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_convex_polygon_shape.svg b/editor/icons/dark/icon_convex_polygon_shape.svg
deleted file mode 100644
index 143780da53..0000000000
--- a/editor/icons/dark/icon_convex_polygon_shape.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m8 1l-7 3v8l7 3 7-3-7-11z" fill="#2998ff"/>
-<path d="m8 1051.4-7-3v-8l7 3z" fill="#68b6ff"/>
-<path transform="translate(0 1036.4)" d="m8 1-7 3 7 11 7-3z" fill="#2998ff"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_convex_polygon_shape_2d.svg b/editor/icons/dark/icon_convex_polygon_shape_2d.svg
deleted file mode 100644
index 5bd177d1c6..0000000000
--- a/editor/icons/dark/icon_convex_polygon_shape_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m14 1050.4h-12v-6l6-6 6 6z" fill="none" stroke="#68b6ff" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_copy_node_path.svg b/editor/icons/dark/icon_copy_node_path.svg
deleted file mode 100644
index 6716a34f02..0000000000
--- a/editor/icons/dark/icon_copy_node_path.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<circle cx="3" cy="1048.4" rx="1" ry="1"/>
-<path transform="translate(0 1036.4)" d="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v12c5.52e-5 0.5523 0.44774 0.9999 1 1h12c0.55226-1e-4 0.99994-0.4477 1-1v-8l-5-5h-8zm1 2h6v3c0 0.554 0.44599 1 1 1h3v6h-10v-10zm3 5l-2 4h2l2-4h-2zm4 0l-2 4h2l2-4h-2z" fill-opacity=".78431"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_create_new_scene_from.svg b/editor/icons/dark/icon_create_new_scene_from.svg
deleted file mode 100644
index 5b09b402b0..0000000000
--- a/editor/icons/dark/icon_create_new_scene_from.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 7v6c0 1.1046 0.89543 2 2 2h7v-1h-2v-4h2v-2h4v2h1v-3z" fill="#4f4f4f"/>
-<path d="m0.71129 1040.4 0.28871 1.9791l2.2438-0.3273-0.81826-1.9018-1.7143 0.25zm3.6933-0.5387 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5775 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5774 0.81826 1.9018 1.7143-0.25-0.28871-1.9791-2.2438 0.3273z" fill="#4f4f4f"/>
-<circle cx="-14" cy="1047.4" r="0" fill="#4f4f4f"/>
-<path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#00f010" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_cube_map.svg b/editor/icons/dark/icon_cube_map.svg
deleted file mode 100644
index 39c1debecd..0000000000
--- a/editor/icons/dark/icon_cube_map.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1042.4" width="4" height="4" fill="#00f010"/>
-<rect x="4" y="1042.4" width="4" height="4" fill="#ff4040"/>
-<rect x="8" y="1042.4" width="4" height="4" fill="#00f010"/>
-<rect x="12" y="1042.4" width="4" height="4" fill="#ff4040"/>
-<rect x="4" y="1038.4" width="4" height="4" fill="#5caeff"/>
-<rect x="4" y="1046.4" width="4" height="4" fill="#5caeff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_cube_mesh.svg b/editor/icons/dark/icon_cube_mesh.svg
deleted file mode 100644
index cf5589e942..0000000000
--- a/editor/icons/dark/icon_cube_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 14.999999 14.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1037.4)">
-<path d="m7.5 1038.2-6.5625 3.2804v6.772l0.49015 0.246 6.0723 3.0344 6.5625-3.2804v-6.772zm0 1.9831 3.6926 1.8463-3.6926 1.8463-3.6926-1.8463zm-4.7889 3.2804 3.9022 1.9502v3.6944l-3.9022-1.952zm9.5779 0v3.6926l-3.9022 1.952v-3.6944z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fea900" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve.svg b/editor/icons/dark/icon_curve.svg
deleted file mode 100644
index 9cc935c38f..0000000000
--- a/editor/icons/dark/icon_curve.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#4f4f4f" stroke-width="2">
-<path d="m2 1038.4v12h12" stroke-linecap="square" stroke-opacity=".32549"/>
-<path d="m2 1050.4c8 0 12-4 12-12" stroke-linecap="round"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_2d.svg b/editor/icons/dark/icon_curve_2d.svg
deleted file mode 100644
index 9697918d32..0000000000
--- a/editor/icons/dark/icon_curve_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m14 1037.4c-3.1667 0-5.1045 0.854-6.082 2.3203-0.97757 1.4664-0.91797 3.1797-0.91797 4.6797s-0.059601 2.7867-0.58203 3.5703c-0.52243 0.7837-1.5846 1.4297-4.418 1.4297a1.0001 1.0001 0 1 0 0 2c3.1667 0 5.1045-0.8539 6.082-2.3203 0.97757-1.4663 0.91797-3.1797 0.91797-4.6797s0.059601-2.7866 0.58203-3.5703c0.52243-0.7836 1.5846-1.4297 4.418-1.4297a1.0001 1.0001 0 1 0 0 -2z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_3d.svg b/editor/icons/dark/icon_curve_3d.svg
deleted file mode 100644
index 9aa63ff537..0000000000
--- a/editor/icons/dark/icon_curve_3d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8.0039 1037.4a1.0001 1.0001 0 0 0 -0.45117 0.1113l-6 3a1.0001 1.0001 0 0 0 0 1.7891l6 3a1.0001 1.0001 0 0 0 0.89453 0l4.5527-2.2754v3.7636l-5 2.5-5.5527-2.7773a1.0001 1.0001 0 0 0 -0.89453 1.7891l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.8946v-6a1.0001 1.0001 0 0 0 -1.4473 -0.8945l-5.5527 2.7773-3.7637-1.8828 4.2109-2.1054a1.0001 1.0001 0 0 0 -0.44336 -1.9004z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_close.svg b/editor/icons/dark/icon_curve_close.svg
deleted file mode 100644
index 42817f31b0..0000000000
--- a/editor/icons/dark/icon_curve_close.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#4f4f4f"/>
-<circle cx="5" cy="1041.4" r="2" fill="#f5f5f5"/>
-<rect x="8" y="1044.4" width="2" height="2" fill="#5caeff"/>
-<circle cx="5" cy="1049.4" r="2" fill="#f5f5f5"/>
-<circle cx="13" cy="1041.4" r="2" fill="#f5f5f5"/>
-<rect x="6" y="1046.4" width="2" height="2" fill="#5caeff"/>
-<rect x="10" y="1042.4" width="2" height="2" fill="#5caeff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_constant.svg b/editor/icons/dark/icon_curve_constant.svg
deleted file mode 100644
index 08436b14e8..0000000000
--- a/editor/icons/dark/icon_curve_constant.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m2 1046.4h8" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_create.svg b/editor/icons/dark/icon_curve_create.svg
deleted file mode 100644
index 8b2f7edb51..0000000000
--- a/editor/icons/dark/icon_curve_create.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#4f4f4f"/>
-<circle cx="5" cy="1041.4" r="2" fill="#00f010"/>
-<circle cx="5" cy="1049.4" r="2" fill="#f5f5f5"/>
-<circle cx="13" cy="1041.4" r="2" fill="#f5f5f5"/>
-<rect x="8" y="1047.4" width="8" height="2" fill="#00f010"/>
-<rect transform="rotate(90)" x="1044.4" y="-13" width="8" height="2" fill="#00f010"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_curve.svg b/editor/icons/dark/icon_curve_curve.svg
deleted file mode 100644
index fdbf9409e5..0000000000
--- a/editor/icons/dark/icon_curve_curve.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#4f4f4f"/>
-<circle cx="5" cy="1041.4" r="2" fill="#5caeff"/>
-<circle cx="5" cy="1049.4" r="2" fill="#f5f5f5"/>
-<circle cx="13" cy="1041.4" r="2" fill="#f5f5f5"/>
-<path d="m1 1045.4 8-8" fill="#5caeff" fill-rule="evenodd" stroke="#5caeff" stroke-width="1px"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_delete.svg b/editor/icons/dark/icon_curve_delete.svg
deleted file mode 100644
index c666b5f6d1..0000000000
--- a/editor/icons/dark/icon_curve_delete.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#4f4f4f"/>
-<circle cx="5" cy="1041.4" r="2" fill="#ff4040"/>
-<circle cx="5" cy="1049.4" r="2" fill="#f5f5f5"/>
-<circle cx="13" cy="1041.4" r="2" fill="#f5f5f5"/>
-<path d="m8.4645 1046.2 2.1213 2.1213-2.1213 2.1213 1.4142 1.4142l2.1213-2.1213 2.1213 2.1213 1.4142-1.4142-2.1213-2.1213 2.1213-2.1213-1.4142-1.4142-2.1213 2.1213-2.1213-2.1213-1.4142 1.4142z" fill="#ff4040"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_edit.svg b/editor/icons/dark/icon_curve_edit.svg
deleted file mode 100644
index f24840f054..0000000000
--- a/editor/icons/dark/icon_curve_edit.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#4f4f4f"/>
-<circle cx="5" cy="1041.4" r="2" fill="#5caeff"/>
-<circle cx="5" cy="1049.4" r="2" fill="#f5f5f5"/>
-<circle cx="13" cy="1041.4" r="2" fill="#f5f5f5"/>
-<path d="m16 1047.7-8-3.291 3.291 8 0.9471-2.8201 1.8836 1.8835 0.9418-0.9418-1.8836-1.8835z" fill="#5caeff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_in.svg b/editor/icons/dark/icon_curve_in.svg
deleted file mode 100644
index a79664642e..0000000000
--- a/editor/icons/dark/icon_curve_in.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m2 1050.4c5 0 8-3 8-8" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_in_out.svg b/editor/icons/dark/icon_curve_in_out.svg
deleted file mode 100644
index c1b4db7787..0000000000
--- a/editor/icons/dark/icon_curve_in_out.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m2 1050.4c5 0 3-8 8-8" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_linear.svg b/editor/icons/dark/icon_curve_linear.svg
deleted file mode 100644
index 21770628a9..0000000000
--- a/editor/icons/dark/icon_curve_linear.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m2 1050.4 8-8" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_out.svg b/editor/icons/dark/icon_curve_out.svg
deleted file mode 100644
index 69cbef8bce..0000000000
--- a/editor/icons/dark/icon_curve_out.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m2 1050.4c0-5 3-8 8-8" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_out_in.svg b/editor/icons/dark/icon_curve_out_in.svg
deleted file mode 100644
index 833deed675..0000000000
--- a/editor/icons/dark/icon_curve_out_in.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="12" height="12" version="1.1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m2 1050.4c0-5 8-3 8-8" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_curve_texture.svg b/editor/icons/dark/icon_curve_texture.svg
deleted file mode 100644
index 3648f5c73b..0000000000
--- a/editor/icons/dark/icon_curve_texture.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1c-0.55228 0-1 0.44772-1 1v9.1602c0.32185-0.10966 0.66-0.16382 1-0.16016 0.33117 0 0.66575-0.007902 1-0.013672v-7.9863h10v1.1348c0.29007-0.10393 0.59442-0.16256 0.90234-0.17383 0.37315-0.012796 0.74541 0.044169 1.0977 0.16797v-2.1289c0-0.55228-0.44772-1-1-1h-12zm7 4v1h-1v1h-2v1h-1v1h-1v1h2 2 0.39062c1.1119-0.56677 1.9678-1.4538 2.6094-3.4727v-0.52734h-1v-1h-1zm4.9668 0.98828a1.0001 1.0001 0 0 0 -0.92774 0.73828c-0.92743 3.246-2.6356 4.6825-4.6523 5.4668-2.0168 0.7843-4.3867 0.80664-6.3867 0.80664a1.0001 1.0001 0 1 0 0 2c2 0 4.6301 0.023994 7.1133-0.94141 2.4832-0.9657 4.7751-3.0292 5.8477-6.7832a1.0001 1.0001 0 0 0 -0.99414 -1.2871z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_cylinder_mesh.svg b/editor/icons/dark/icon_cylinder_mesh.svg
deleted file mode 100644
index 01b6571884..0000000000
--- a/editor/icons/dark/icon_cylinder_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 14.999999 14.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1037.4)">
-<path transform="matrix(.9375 0 0 .9375 0 1037.4)" d="m8 1c-1.7469 0-3.328 0.22648-4.5586 0.63672-0.61528 0.20512-1.1471 0.45187-1.5898 0.80078s-0.85156 0.88101-0.85156 1.5625v8c0 0.68149 0.40884 1.2155 0.85156 1.5645s0.97457 0.59577 1.5898 0.80078c1.2306 0.41024 2.8117 0.63477 4.5586 0.63477s3.328-0.22453 4.5586-0.63477c0.61527-0.20501 1.1471-0.45187 1.5898-0.80078 0.44272-0.34891 0.85156-0.88296 0.85156-1.5645v-8c0-0.68149-0.40884-1.2136-0.85156-1.5625-0.44272-0.34891-0.97457-0.59566-1.5898-0.80078-1.2306-0.41024-2.8117-0.63672-4.5586-0.63672zm0 2c1.5668 0 2.9867 0.22145 3.9277 0.53516 0.46368 0.15456 0.80138 0.33741 0.96875 0.4668-0.16752 0.12928-0.50546 0.3105-0.96875 0.46484-0.94102 0.31371-2.361 0.5332-3.9277 0.5332s-2.9867-0.2195-3.9277-0.5332c-0.46329-0.15435-0.80123-0.33556-0.96875-0.46484 0.16737-0.12939 0.50507-0.31224 0.96875-0.4668 0.94102-0.31371 2.361-0.53516 3.9277-0.53516zm-5 3.1875c0.1468 0.059071 0.2835 0.12512 0.44141 0.17773 1.2306 0.41024 2.8117 0.63477 4.5586 0.63477s3.328-0.22453 4.5586-0.63477c0.15791-0.052617 0.29461-0.11866 0.44141-0.17773v5.8125c-0.16752 0.12928-0.60898 0.31245-1.0723 0.4668-0.94102 0.31371-2.361 0.5332-3.9277 0.5332s-2.9867-0.2195-3.9277-0.5332c-0.46329-0.15435-0.90474-0.33752-1.0723-0.4668z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fea900" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_damped_spring_joint_2d.svg b/editor/icons/dark/icon_damped_spring_joint_2d.svg
deleted file mode 100644
index b3a8e89ef9..0000000000
--- a/editor/icons/dark/icon_damped_spring_joint_2d.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-opacity=".98824">
-<path transform="translate(0 1036.4)" d="m4 3v2l8 3v-2zm0 5v2l8 3v-2z" fill="#0843ff"/>
-<path transform="translate(0 1036.4)" d="m4 3v2l8-2v-2zm0 5v2l8-2v-2zm0 5v2l8-2v-2z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_debug.svg b/editor/icons/dark/icon_debug.svg
deleted file mode 100644
index 3819c10c18..0000000000
--- a/editor/icons/dark/icon_debug.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="scale(1,-1)" d="m10.828-1039.5a4 4 0 0 1 -2.8284 1.1716 4 4 0 0 1 -2.8284 -1.1716" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<ellipse cx="8" cy="1047.4" rx="3.6445" ry="1.6348" fill="none" stroke-width="0"/>
-<circle cx="8" cy="1047.4" r="4" fill="#4f4f4f" stroke-width="0"/>
-<path d="m5 1047.4h-3" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-<path d="m10 1047.4h4" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-<path d="m6 1045.4c-2 0-3-2-3-3" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-<path d="m10 1045.4c2 0 3-2 3-3" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-<path d="m6 1049.4c-1 0-2 1-3 2" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-<path d="m10 1049.4c1 0 2 1 3 2" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-<circle cx="8" cy="1043.4" r="2" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_debug_continue.svg b/editor/icons/dark/icon_debug_continue.svg
deleted file mode 100644
index 94c14d80dd..0000000000
--- a/editor/icons/dark/icon_debug_continue.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="5" y="1043.4" width="6" height="2" fill="#ff4040"/>
-<g transform="matrix(-.71429 0 0 .88889 2.4999 121.82)" fill="#ff4040">
-<path transform="matrix(0 1.4412 1.2943 0 1331.1 1030.7)" d="m8.1225-1036.6h-3.1225-3.1225l1.5612-2.7042 1.5612-2.7041 1.5612 2.7041z" fill="#ff4040"/>
-</g>
-<circle cx="4" cy="1044.4" r="3" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_debug_next.svg b/editor/icons/dark/icon_debug_next.svg
deleted file mode 100644
index 2c1a7d2496..0000000000
--- a/editor/icons/dark/icon_debug_next.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect transform="rotate(90)" x="1037.4" y="-5" width="10" height="2" fill="#ff4040"/>
-<g transform="matrix(0 -.57144 -.66666 0 695.91 1041.4)" fill="#ff4040">
-<path transform="matrix(0 1.4412 1.2943 0 1331.1 1030.7)" d="m8.1225-1036.6h-3.1225-3.1225l1.5612-2.7042 1.5612-2.7041 1.5612 2.7041z" fill="#ff4040"/>
-</g>
-<rect x="7" y="1037.4" width="8" height="2" fill="#4f4f4f"/>
-<rect x="9" y="1041.4" width="6" height="2" fill="#4f4f4f"/>
-<rect x="9" y="1045.4" width="6" height="2" fill="#4f4f4f"/>
-<rect x="7" y="1049.4" width="8" height="2" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_debug_step.svg b/editor/icons/dark/icon_debug_step.svg
deleted file mode 100644
index ca708b5f35..0000000000
--- a/editor/icons/dark/icon_debug_step.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect transform="rotate(90)" x="1037.4" y="-3" width="10" height="2" fill="#ff4040"/>
-<g transform="matrix(-.57144 0 0 .66666 -2.0001 354.46)" fill="#ff4040">
-<path transform="matrix(0 1.4412 1.2943 0 1331.1 1030.7)" d="m8.1225-1036.6h-3.1225-3.1225l1.5612-2.7042 1.5612-2.7041 1.5612 2.7041z" fill="#ff4040"/>
-</g>
-<rect x="7" y="1037.4" width="8" height="2" fill="#4f4f4f"/>
-<rect x="9" y="1041.4" width="6" height="2" fill="#4f4f4f"/>
-<rect x="9" y="1045.4" width="6" height="2" fill="#4f4f4f"/>
-<rect x="7" y="1049.4" width="8" height="2" fill="#4f4f4f"/>
-<rect transform="rotate(90)" x="1045.4" y="-4" width="2" height="3" fill="#ff4040"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_default_project_icon.svg b/editor/icons/dark/icon_default_project_icon.svg
deleted file mode 100644
index d16d137550..0000000000
--- a/editor/icons/dark/icon_default_project_icon.svg
+++ /dev/null
@@ -1,33 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -988.36)">
-<path transform="translate(0 988.36)" d="m8 0c-4.432 0-8 3.568-8 8v48c0 4.432 3.568 8 8 8h48c4.432 0 8-3.568 8-8v-48c0-4.432-3.568-8-8-8z" fill="#355570" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path transform="translate(0 988.36)" d="m8 0c-4.432 0-8 3.568-8 8v48c0 4.432 3.568 8 8 8h48c4.432 0 8-3.568 8-8v-48c0-4.432-3.568-8-8-8zm0 2h48c3.324 0 6 2.676 6 6v48c0 3.324-2.676 6-6 6h-48c-3.324 0-6-2.676-6-6v-48c0-3.324 2.676-6 6-6z" fill-opacity=".19608" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path transform="translate(0 988.36)" d="m27.254 10c-2.1314 0.47383-4.2401 1.134-6.2168 2.1289 0.04521 1.7455 0.15796 3.4164 0.38672 5.1152-0.76768 0.4919-1.574 0.91443-2.291 1.4902-0.72854 0.5604-1.4731 1.0965-2.1328 1.752-1.3179-0.8716-2.7115-1.691-4.1484-2.4141-1.549 1.667-2.9985 3.4672-4.1816 5.4805 0.89011 1.4399 1.8209 2.7894 2.8242 4.0703h0.027343v9.9453 1.2617 1.1504l-0.009765 1.6309h-0.001953c0.0031 0.7321 0.011718 1.5356 0.011718 1.6953 0 7.1942 9.1264 10.652 20.465 10.691h0.013672 0.013672c11.338-0.04 20.461-3.4972 20.461-10.691 0-0.1626 0.010282-0.96271 0.013672-1.6953h-0.001953l-0.011719-1.6309v-0.98633l0.003907-0.001953v-11.369h0.027343c1.0035-1.2809 1.9337-2.6304 2.8242-4.0703-1.1827-2.0133-2.6327-3.8135-4.1816-5.4805-1.4366 0.7231-2.8325 1.5425-4.1504 2.4141-0.65947-0.6555-1.4013-1.1916-2.1309-1.752-0.71682-0.5758-1.5248-0.99833-2.291-1.4902 0.22813-1.6988 0.3413-3.3697 0.38672-5.1152-1.977-0.99494-4.0863-1.6551-6.2188-2.1289-0.85139 1.4309-1.6285 2.9812-2.3066 4.4961-0.80409-0.1344-1.613-0.18571-2.4219-0.19531h-0.015625-0.015625c-0.81037 0.01-1.6176 0.060513-2.4219 0.19531-0.67768-1.5149-1.4559-3.0652-2.3086-4.4961z" fill="#fff" stroke="#fff" stroke-linejoin="round" stroke-width="3"/>
-<g transform="matrix(.050279 0 0 .050279 6.2574 989.54)" stroke-width=".32031">
-<g transform="matrix(4.1626 0 0 -4.1626 919.24 771.67)">
-<path d="m0 0s-0.325 1.994-0.515 1.976l-36.182-3.491c-2.879-0.278-5.115-2.574-5.317-5.459l-0.994-14.247-27.992-1.997-1.904 12.912c-0.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-0.994 14.247c-0.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-0.187 0.018-0.324-1.978-0.511-1.978l-0.049-7.83 30.658-4.944 1.004-14.374c0.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c0.146-0.01 0.29-0.016 0.434-0.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c0.423-2.871 2.93-5.037 5.831-5.037 0.142 0 0.284 5e-3 0.423 0.015l38.556 2.75c2.911 0.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 104.7 525.91)">
-<path d="m0 0v-59.041c0.108-1e-3 0.216-5e-3 0.323-0.015l36.196-3.49c1.896-0.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c0.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c0.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c0.107 0.01 0.214 0.014 0.322 0.015v4.711l0.015 5e-3v54.325h0.134c4.795 6.12 9.232 12.569 13.487 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842 0.642-7.702 0.88-11.567 0.926v6e-3c-0.027 0-0.052-6e-3 -0.075-6e-3 -0.024 0-0.049 6e-3 -0.073 6e-3v-6e-3c-3.872-0.046-7.729-0.284-11.572-0.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17 0.216-8.34 0.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.253-6.88 8.693-13.329 13.487-19.449z" fill="#478cbf"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 784.07 817.24)">
-<path d="m0 0-1.121-16.063c-0.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-0.094-7e-3 -0.188-0.01-0.281-0.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-0.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936 0.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c0.015-3.498 0.06-7.33 0.06-8.093 0-34.374 43.605-50.896 97.781-51.086h0.133c54.176 0.19 97.766 16.712 97.766 51.086 0 0.777 0.047 4.593 0.063 8.093z" fill="#478cbf"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 389.21 625.67)">
-<path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 367.37 631.06)">
-<path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 511.99 724.74)">
-<path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 634.79 625.67)">
-<path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 656.64 631.06)">
-<path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042"/>
-</g>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dependency_changed.svg b/editor/icons/dark/icon_dependency_changed.svg
deleted file mode 100644
index bba1f032ca..0000000000
--- a/editor/icons/dark/icon_dependency_changed.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-1 2h2v7h-2v-7zm0 8h2v2h-2v-2z" fill="#ff4040"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-1 2h2v7h-2v-7zm0 8h2v2h-2v-2z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dependency_changed_hl.svg b/editor/icons/dark/icon_dependency_changed_hl.svg
deleted file mode 100644
index b8c45153ca..0000000000
--- a/editor/icons/dark/icon_dependency_changed_hl.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-1 2h2v7h-2v-7zm0 8h2v2h-2v-2z" fill="#ff4040"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dependency_local_changed.svg b/editor/icons/dark/icon_dependency_local_changed.svg
deleted file mode 100644
index e6021b9a80..0000000000
--- a/editor/icons/dark/icon_dependency_local_changed.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -3 3.8672v0.13281h-2v-2h1a2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2 2 2 0 0 0 -2 2h-2a4 4 0 0 1 4 -4zm-1 9h2v2h-2v-2z" fill="#fea900"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -3 3.8672v0.13281h-2v-2h1a2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2 2 2 0 0 0 -2 2h-2a4 4 0 0 1 4 -4zm-1 9h2v2h-2v-2z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dependency_local_changed_hl.svg b/editor/icons/dark/icon_dependency_local_changed_hl.svg
deleted file mode 100644
index 89d9c663cb..0000000000
--- a/editor/icons/dark/icon_dependency_local_changed_hl.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -3 3.8672v0.13281h-2v-2h1a2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2 2 2 0 0 0 -2 2h-2a4 4 0 0 1 4 -4zm-1 9h2v2h-2v-2z" fill="#fea900"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dependency_ok.svg b/editor/icons/dark/icon_dependency_ok.svg
deleted file mode 100644
index aecdbb63ba..0000000000
--- a/editor/icons/dark/icon_dependency_ok.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm3.1816 3.9297l1.4141 1.4141-4.2422 4.2422-0.70703 0.70703-0.70703 0.70703-3.5352-3.5352 1.4141-1.4141 2.1211 2.1211 4.2422-4.2422z" fill="#00f010"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm3.1816 3.9297l1.4141 1.4141-4.2422 4.2422-0.70703 0.70703-0.70703 0.70703-3.5352-3.5352 1.4141-1.4141 2.1211 2.1211 4.2422-4.2422z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dependency_ok_hl.svg b/editor/icons/dark/icon_dependency_ok_hl.svg
deleted file mode 100644
index 8de94755b1..0000000000
--- a/editor/icons/dark/icon_dependency_ok_hl.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm3.1816 3.9297l1.4141 1.4141-4.2422 4.2422-0.70703 0.70703-0.70703 0.70703-3.5352-3.5352 1.4141-1.4141 2.1211 2.1211 4.2422-4.2422z" fill="#00f010"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_directional_light.svg b/editor/icons/dark/icon_directional_light.svg
deleted file mode 100644
index a595465534..0000000000
--- a/editor/icons/dark/icon_directional_light.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v3h2v-3h-2zm-2.5352 2.0508l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm7.0703 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2h-3zm11 0v2h3v-2h-3zm-7.5352 3.1211l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm7.0703 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-4.5352 1.8789v3h2v-3h-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_distraction_free.svg b/editor/icons/dark/icon_distraction_free.svg
deleted file mode 100644
index 2ec6f20fd2..0000000000
--- a/editor/icons/dark/icon_distraction_free.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m3.7578 2.3438l-1.4141 1.4141 2.9492 2.9492 1.4141-1.4141-2.9492-2.9492zm8.4844 0l-2.9492 2.9492 1.4141 1.4141 2.9492-2.9492-1.4141-1.4141zm-6.9492 6.9492l-2.9492 2.9492 1.4141 1.4141 2.9492-2.9492-1.4141-1.4141zm5.4141 0l-1.4141 1.4141 2.9492 2.9492 1.4141-1.4141-2.9492-2.9492z"/>
-<path d="m1 1051.4v-5l5 5z" fill-rule="evenodd"/>
-<path d="m15 1051.4v-5l-5 5z" fill-rule="evenodd"/>
-<path d="m15 1037.4v5l-5-5z" fill-rule="evenodd"/>
-<path d="m1 1037.4v5l5-5z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_duplicate.svg b/editor/icons/dark/icon_duplicate.svg
deleted file mode 100644
index 9bb1e24b30..0000000000
--- a/editor/icons/dark/icon_duplicate.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 1v11h9v-6h-5v-5h-4zm5 0v4h4l-4-4zm-8 3v11h2 8v-2h-8v-9h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dynamic_font.svg b/editor/icons/dark/icon_dynamic_font.svg
deleted file mode 100644
index a7fb18c9cc..0000000000
--- a/editor/icons/dark/icon_dynamic_font.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m1 1037.4v2 1h1a1 1 0 0 1 1 -1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1 -1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2-4z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m4 5v2 1h1a1 1 0 0 1 1 -1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1 -1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2-4z" fill="#5caeff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_dynamic_font_data.svg b/editor/icons/dark/icon_dynamic_font_data.svg
deleted file mode 100644
index 9655726f11..0000000000
--- a/editor/icons/dark/icon_dynamic_font_data.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 1h1a1 1 0 0 1 1 -1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1 -1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2-4zm0 5v2h2v-2h-2zm0 3v2h2v-2h-2zm0 3v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m4 5v2 1h1a1 1 0 0 1 1 -1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1 -1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2-4z" fill="#ff4040"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_edit.svg b/editor/icons/dark/icon_edit.svg
deleted file mode 100644
index 5d03cdfa29..0000000000
--- a/editor/icons/dark/icon_edit.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m1.7071 1047.8-0.70711 3.5356l3.5355-0.7071 7.7782-7.7782-2.8284-2.8284zm9.1924-9.1924 2.8284 2.8285 1.4142-1.4142-2.8284-2.8285z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_edit_key.svg b/editor/icons/dark/icon_edit_key.svg
deleted file mode 100644
index ad4e626ace..0000000000
--- a/editor/icons/dark/icon_edit_key.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m1.7071 1047.8-0.70711 3.5356l3.5355-0.7071 7.7782-7.7782-2.8284-2.8284zm9.1924-9.1924 2.8284 2.8285 1.4142-1.4142-2.8284-2.8285z"/>
-<ellipse cx="3.5" cy="1039.9" rx="2.5" ry="2.5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_edit_pivot.svg b/editor/icons/dark/icon_edit_pivot.svg
deleted file mode 100644
index bac968e3a2..0000000000
--- a/editor/icons/dark/icon_edit_pivot.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v4h2v-4h-2zm-6 6v2h4v-2h-4zm10 0v0.61328l3.3711 1.3867h0.62891v-2h-4zm-3 1l3.291 8 0.94726-2.8203 1.8828 1.8828 0.94336-0.94141-1.8848-1.8828 2.8203-0.94726-8-3.291zm-1 3v4h2v-0.625l-1.3887-3.375h-0.61133z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_edit_resource.svg b/editor/icons/dark/icon_edit_resource.svg
deleted file mode 100644
index 996b1bf7d6..0000000000
--- a/editor/icons/dark/icon_edit_resource.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path transform="translate(0 1044.4)" d="m3.9902-0.0097656a1.0001 1.0001 0 0 0 -0.69727 1.7168l1.293 1.293h-3.5859v2h3.5859l-1.293 1.293a1.0001 1.0001 0 1 0 1.4141 1.4141l3-3a1.0001 1.0001 0 0 0 0 -1.4141l-3-3a1.0001 1.0001 0 0 0 -0.7168 -0.30273z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".78431" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_editor_3d_handle.svg b/editor/icons/dark/icon_editor_3d_handle.svg
deleted file mode 100644
index 189baf3dad..0000000000
--- a/editor/icons/dark/icon_editor_3d_handle.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="8" cy="1044.4" r="7" fill="#fff"/>
-<circle cx="8" cy="1044.4" r="5" fill="#ff8484"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_editor_control_anchor.svg b/editor/icons/dark/icon_editor_control_anchor.svg
deleted file mode 100644
index eeee2c182f..0000000000
--- a/editor/icons/dark/icon_editor_control_anchor.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8.832 6.1445a4 4 0 0 1 -2.6914 2.6855l9.8594 7.1699-7.168-9.8555z" fill="#a5efac" fill-rule="evenodd"/>
-<ellipse cx="3" cy="1039.4" r="2" fill="#6e6e6e"/>
-<ellipse cx="4" cy="1040.4" rx="4" ry="4" fill="#a5efac" style="paint-order:fill markers stroke"/>
-<circle cx="5" cy="1041.4" r="0" fill="#a5efac" style="paint-order:fill markers stroke"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_editor_handle.svg b/editor/icons/dark/icon_editor_handle.svg
deleted file mode 100644
index 7e58aaa803..0000000000
--- a/editor/icons/dark/icon_editor_handle.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<ellipse cx="4" cy="1048.4" rx="4" ry="4" fill="#fff"/>
-<ellipse cx="4" cy="1048.4" rx="2.8572" ry="2.8571" fill="#ff8484"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_editor_pivot.svg b/editor/icons/dark/icon_editor_pivot.svg
deleted file mode 100644
index d59d2d804d..0000000000
--- a/editor/icons/dark/icon_editor_pivot.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 0v6h-6v4h6v6h4v-6h6v-4h-6v-6h-4zm1 7h2v2h-2v-2z" fill="#fff" fill-opacity=".70588"/>
-<path transform="translate(0 1036.4)" d="m7 1v5h2v-5h-2zm-6 6v2h5v-2h-5zm9 0v2h5v-2h-5zm-3 3v5h2v-5h-2z" fill="#ff8484" fill-opacity=".58824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_editor_plugin.svg b/editor/icons/dark/icon_editor_plugin.svg
deleted file mode 100644
index 7c91902998..0000000000
--- a/editor/icons/dark/icon_editor_plugin.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path d="m2 1038.4v8h8v-8z" fill-rule="evenodd" stroke="#4f4f4f" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2"/>
-<circle cx="13" cy="1042.4" r="2"/>
-<circle cx="6" cy="1049.4" r="2"/>
-<rect x="5" y="1046.4" width="2" height="2"/>
-<rect x="10" y="1041.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_environment.svg b/editor/icons/dark/icon_environment.svg
deleted file mode 100644
index 833346bd28..0000000000
--- a/editor/icons/dark/icon_environment.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#4f4f4f">
-<circle cx="8" cy="1044.4" r="6" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m2 1044.4c4.5932 1.582 8.3985 1.0627 12 0" stroke-width="1.5"/>
-<path d="m8 1038.4c-3 4-3 8 0 12" stroke-width="1.5"/>
-<path d="m8 1038.4c3 4 3 8 0 12" stroke-width="1.5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_error.svg b/editor/icons/dark/icon_error.svg
deleted file mode 100644
index ae74328509..0000000000
--- a/editor/icons/dark/icon_error.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect x="2.2204e-16" y="1044.4" width="8" height="8" ry="4" fill="#ff4040"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_error_sign.svg b/editor/icons/dark/icon_error_sign.svg
deleted file mode 100644
index ae384978a5..0000000000
--- a/editor/icons/dark/icon_error_sign.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1020.4)">
-<path d="m10 1048.4h12l6-6v-12l-6-6h-12l-6 6v12z" fill="#ff4040" fill-rule="evenodd"/>
-<rect x="14" y="1028.4" width="4" height="9" fill="#000000"/>
-<rect x="14" y="1040.4" width="4" height="4" fil#000000fff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_event_player.svg b/editor/icons/dark/icon_event_player.svg
deleted file mode 100644
index 2d13800c91..0000000000
--- a/editor/icons/dark/icon_event_player.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m1 1v14h14v-14h-14zm2 2h10v10h-10v-10z"/>
-<path transform="translate(0 1036.4)" d="m5 3v6h2v-6h-2zm4 0v6h2v-6h-2z"/>
-<rect x="5" y="1039.4" width="1" height="10"/>
-<rect x="9" y="1039.4" width="1" height="10"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_favorites.svg b/editor/icons/dark/icon_favorites.svg
deleted file mode 100644
index 3343ca69ec..0000000000
--- a/editor/icons/dark/icon_favorites.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8 1038.1-2.3741 4.0973-4.6259 1.0978l3.2361 3.4074-0.35866 4.6735 4.1389-1.9766 4.1572 1.9421-0.39534-4.6532 3.2218-3.3932-4.6259-1.0978-2.3741-4.0973z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_file_big.svg b/editor/icons/dark/icon_file_big.svg
deleted file mode 100644
index 52c224f6a5..0000000000
--- a/editor/icons/dark/icon_file_big.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -988.36)">
-<g transform="translate(0 -1.6949e-5)">
-<path transform="translate(0 988.36)" d="m14 5c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-0.007812c0.00212-0.24832-0.079273-0.50098-0.28516-0.70703l-16-16c-0.18786-0.18693-0.44246-0.28939-0.70703-0.28906v-0.0039062h-23zm0 2h22v2 10c0 2.1987 1.8013 4 4 4h10 2v32c0 1.1253-0.87472 2-2 2h-36c-1.1253 0-2-0.8747-2-2v-46c0-1.1253 0.87472-2 2-2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#000000" fill-opacity=".58824" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_file_dialog.svg b/editor/icons/dark/icon_file_dialog.svg
deleted file mode 100644
index 542894b906..0000000000
--- a/editor/icons/dark/icon_file_dialog.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.8954-2 2v1h14v-1c0-1.1046-0.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_file_list.svg b/editor/icons/dark/icon_file_list.svg
deleted file mode 100644
index 12678c2873..0000000000
--- a/editor/icons/dark/icon_file_list.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 2v2h2v-2h-2zm4 0v2h8v-2h-8zm-4 5v2h2v-2h-2zm4 0v2h8v-2h-8zm-4 5v2h2v-2h-2zm4 0v2h8v-2h-8z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_file_server.svg b/editor/icons/dark/icon_file_server.svg
deleted file mode 100644
index 02bc363c19..0000000000
--- a/editor/icons/dark/icon_file_server.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#c5c5c5">
-<path transform="translate(0 1036.4)" d="m1 8v3h14v-3h-14zm1 1h1v1h-1v-1zm2 0h1v1h-1v-1zm-3 3v3h14v-3h-14zm1 1h1v1h-1v-1zm2 0h1v1h-1v-1z"/>
-<rect x="5" y="1038.4" width="6" height="4"/>
-<rect x="5" y="1037.4" width="3" height="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_file_server_active.svg b/editor/icons/dark/icon_file_server_active.svg
deleted file mode 100644
index ccb9b97336..0000000000
--- a/editor/icons/dark/icon_file_server_active.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#00f010">
-<path transform="translate(0 1036.4)" d="m1 8v3h14v-3h-14zm1 1h1v1h-1v-1zm2 0h1v1h-1v-1zm-3 3v3h14v-3h-14zm1 1h1v1h-1v-1zm2 0h1v1h-1v-1z"/>
-<rect x="5" y="1038.4" width="6" height="4"/>
-<rect x="5" y="1037.4" width="3" height="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_file_thumbnail.svg b/editor/icons/dark/icon_file_thumbnail.svg
deleted file mode 100644
index bd1d4d2fc3..0000000000
--- a/editor/icons/dark/icon_file_thumbnail.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 2v5h5v-5h-5zm7 0v5h5v-5h-5zm-7 7v5h5v-5h-5zm7 0v5h5v-5h-5z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_fixed_material.svg b/editor/icons/dark/icon_fixed_material.svg
deleted file mode 100644
index 47cf9189d6..0000000000
--- a/editor/icons/dark/icon_fixed_material.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8 1037.4a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_fixed_spatial_material.svg b/editor/icons/dark/icon_fixed_spatial_material.svg
deleted file mode 100644
index 4e634280bf..0000000000
--- a/editor/icons/dark/icon_fixed_spatial_material.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -4.8887 2h2.8887 6.8965a7 7 0 0 0 -4.8965 -2z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m3.1113 3a7 7 0 0 0 -1.4277 2h2.3164a2 2 0 0 1 2 -2h-2.8887zm2.8887 0a2 2 0 0 1 2 2h6.3145a7 7 0 0 0 -1.418 -2h-6.8965z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m1.6836 5a7 7 0 0 0 -0.60547 2h4.9219a2 2 0 0 1 -2 -2h-2.3164zm4.3164 2h8.9199a7 7 0 0 0 -0.60547 -2h-6.3145a2 2 0 0 1 -2 2z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1.0781 7a7 7 0 0 0 -0.078125 1 7 7 0 0 0 0.080078 1h13.842a7 7 0 0 0 0.078125 -1 7 7 0 0 0 -0.080078 -1h-8.9199-4.9219z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1.0801 9a7 7 0 0 0 0.60547 2h12.631a7 7 0 0 0 0.60547 -2h-13.842z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m3.1035 13a7 7 0 0 0 4.8965 2 7 7 0 0 0 4.8887 -2h-9.7852z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m1.6855 11a7 7 0 0 0 1.418 2h9.7852a7 7 0 0 0 1.4277 -2h-12.631z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_folder.svg b/editor/icons/dark/icon_folder.svg
deleted file mode 100644
index a127f00ae1..0000000000
--- a/editor/icons/dark/icon_folder.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 2a1 1 0 0 0 -1 1v2 6 2a1 1 0 0 0 1 1h12a1 1 0 0 0 1 -1v-7a1 1 0 0 0 -1 -1h-4a1 1 0 0 1 -1 -1v-1a1 1 0 0 0 -1 -1h-6z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_folder_big.svg b/editor/icons/dark/icon_folder_big.svg
deleted file mode 100644
index 440907e33b..0000000000
--- a/editor/icons/dark/icon_folder_big.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -988.36)">
-<path transform="translate(0 988.36)" d="m13 11.996a5.0039 5.0039 0 0 0 -5.0039 5.0039 5.0039 5.0039 0 0 0 0.0039062 0.11719v2.8828 8 22.92a5.0039 5.0039 0 0 0 -0.0039062 0.076172 5.0039 5.0039 0 0 0 5.0039 5.0039h37.996a5.0039 5.0039 0 0 0 5.0039 -5.0039v-25.916a5.0039 5.0039 0 0 0 0.003906 -0.076172 5.0039 5.0039 0 0 0 -5.0039 -5.0039h-11v-0.039062a3.5 3.5 0 0 1 -0.5 0.039062 3.5 3.5 0 0 1 -3.5 -3.5v0.38281a5.0039 5.0039 0 0 0 -5 -4.8867 5.0039 5.0039 0 0 0 -0.11719 0.003906h-17.807a5.0039 5.0039 0 0 0 -0.076172 -0.003906zm23 4.5039a3.5 3.5 0 0 1 0.041016 -0.5h-0.041016v0.5z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_font.svg b/editor/icons/dark/icon_font.svg
deleted file mode 100644
index f89b408383..0000000000
--- a/editor/icons/dark/icon_font.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="1" y="1037.4" width="14" height="2"/>
-<rect x="7" y="1037.4" width="2" height="14"/>
-<rect x="5" y="1050.4" width="6" height="1"/>
-<rect transform="rotate(90)" x="1037.4" y="-2" width="4" height="1"/>
-<rect transform="rotate(90)" x="1037.4" y="-15" width="4" height="1"/>
-<path transform="translate(0 1036.4)" d="m2 3v2a2 2 0 0 1 2 -2h-2z"/>
-<path transform="translate(0 1036.4)" d="m12 3a2 2 0 0 1 2 2v-2h-2z"/>
-<path d="m5 1050.4a2 2 0 0 0 2 -2v2h-2z"/>
-<path d="m11 1050.4a2 2 0 0 1 -2 -2v2h2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_forward.svg b/editor/icons/dark/icon_forward.svg
deleted file mode 100644
index a02f36d314..0000000000
--- a/editor/icons/dark/icon_forward.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="16" version="1.1" viewBox="0 0 8 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1038.4 4 6-4 6" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_g_d_native_library.svg b/editor/icons/dark/icon_g_d_native_library.svg
deleted file mode 100644
index 24a18eceb0..0000000000
--- a/editor/icons/dark/icon_g_d_native_library.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1l-0.56445 2.2578a5 5 0 0 0 -0.68945 0.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -0.28516 0.68555l-2.2539 0.5625v2l2.2578 0.56445a5 5 0 0 0 0.2793 0.6875l-1.1934 1.9902 1.4141 1.4141 1.9941-1.1953a5 5 0 0 0 0.68555 0.28516l0.5625 2.2539v-5.2695a2 2 0 0 1 -1 -1.7305 2 2 0 0 1 1 -1.7285v-0.27148h1 4.5762a5 5 0 0 0 -0.11328 -0.25195l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -0.68555 -0.28516l-0.5625-2.2539h-2zm2 7v1 5 1h5c0.55228 0 1-0.4477 1-1v-5c0-0.5523-0.44772-1-1-1v4l-1-1-1 1v-4h-3z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_g_d_script.svg b/editor/icons/dark/icon_g_d_script.svg
deleted file mode 100644
index 07718e87b2..0000000000
--- a/editor/icons/dark/icon_g_d_script.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1l-0.56445 2.2578a5 5 0 0 0 -0.68945 0.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -0.28516 0.68555l-2.2539 0.5625v2l2.2578 0.56445a5 5 0 0 0 0.2793 0.6875l-1.1934 1.9902 1.4141 1.4141 1.9941-1.1953a5 5 0 0 0 0.68555 0.28516l0.5625 2.2539h2l0.56445-2.2578a5 5 0 0 0 0.6875 -0.2793l1.9902 1.1934 1.4141-1.4141-1.1953-1.9941a5 5 0 0 0 0.28516 -0.68555l2.2539-0.5625v-2l-2.2578-0.56445a5 5 0 0 0 -0.2793 -0.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -0.68555 -0.28516l-0.5625-2.2539h-2zm1 5a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_g_i_probe.svg b/editor/icons/dark/icon_g_i_probe.svg
deleted file mode 100644
index d88cc782ad..0000000000
--- a/editor/icons/dark/icon_g_i_probe.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4v-2h-3v-10h9v-2h-10zm9 3a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.459v0.54102c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1v-0.54102a4 4 0 0 0 2 -3.459 4 4 0 0 0 -4 -4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-1 8v1h2v-1h-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_g_i_probe_data.svg b/editor/icons/dark/icon_g_i_probe_data.svg
deleted file mode 100644
index a7c8253448..0000000000
--- a/editor/icons/dark/icon_g_i_probe_data.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4v-2h-3v-10h9v-2h-10zm2 3v2h2v-2h-2zm7 0a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.459v0.54102c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1v-0.54102a4 4 0 0 0 2 -3.459 4 4 0 0 0 -4 -4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-7 1v2h2v-2h-2zm0 3v2h2v-2h-2zm6 4v1h2v-1h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_generic_6_d_o_f_joint.svg b/editor/icons/dark/icon_generic_6_d_o_f_joint.svg
deleted file mode 100644
index e5671afa84..0000000000
--- a/editor/icons/dark/icon_generic_6_d_o_f_joint.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a1 1 0 0 0 -1 1v4.8828l-3.5527-1.7773a1 1 0 0 0 -0.48438 -0.10352 1 1 0 0 0 -0.85742 0.55078 1 1 0 0 0 0.44727 1.3418l3.2109 1.6055-3.2109 1.6055a1 1 0 0 0 -0.44727 1.3418 1 1 0 0 0 1.3418 0.44726l3.5527-1.7773v3.8828a1 1 0 0 0 1 1 1 1 0 0 0 1 -1v-3.8828l3.5527 1.7773a1 1 0 0 0 1.3418 -0.44726 1 1 0 0 0 -0.44726 -1.3418l-3.2109-1.6055 3.2109-1.6055a1 1 0 0 0 0.44726 -1.3418 1 1 0 0 0 -0.88672 -0.55273 1 1 0 0 0 -0.45508 0.10547l-3.5527 1.7773v-4.8828a1 1 0 0 0 -1 -1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff5f5f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gizmo_directional_light.svg b/editor/icons/dark/icon_gizmo_directional_light.svg
deleted file mode 100644
index a8739a5a78..0000000000
--- a/editor/icons/dark/icon_gizmo_directional_light.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m64 4a8 8 0 0 0 -8 8v12a8 8 0 0 0 8 8 8 8 0 0 0 8 -8v-12a8 8 0 0 0 -8 -8zm-36.887 15.23a8 8 0 0 0 -5.5391 2.3438 8 8 0 0 0 0 11.312l8.4844 8.4863a8 8 0 0 0 11.314 0 8 8 0 0 0 0 -11.314l-8.4863-8.4844a8 8 0 0 0 -5.7734 -2.3438zm73.539 0a8 8 0 0 0 -5.5391 2.3438l-8.4863 8.4844a8 8 0 0 0 0 11.314 8 8 0 0 0 11.314 0l8.4844-8.4863a8 8 0 0 0 0 -11.312 8 8 0 0 0 -5.7734 -2.3438zm-36.652 20.77a24 24 0 0 0 -24 24 24 24 0 0 0 24 24 24 24 0 0 0 24 -24 24 24 0 0 0 -24 -24zm-52 16a8 8 0 0 0 -8 8 8 8 0 0 0 8 8h12a8 8 0 0 0 8 -8 8 8 0 0 0 -8 -8h-12zm92 0a8 8 0 0 0 -8 8 8 8 0 0 0 8 8h12a8 8 0 0 0 8 -8 8 8 0 0 0 -8 -8h-12zm-68.4 28.285a8 8 0 0 0 -5.541 2.3418l-8.4844 8.4863a8 8 0 0 0 0 11.312 8 8 0 0 0 11.312 0l8.4863-8.4844a8 8 0 0 0 0 -11.314 8 8 0 0 0 -5.7734 -2.3418zm56.568 0a8 8 0 0 0 -5.541 2.3418 8 8 0 0 0 0 11.314l8.4863 8.4844a8 8 0 0 0 11.312 0 8 8 0 0 0 0 -11.312l-8.4844-8.4863a8 8 0 0 0 -5.7734 -2.3418zm-28.168 11.715a8 8 0 0 0 -8 8v12a8 8 0 0 0 8 8 8 8 0 0 0 8 -8v-12a8 8 0 0 0 -8 -8z" fill="#f7f5cf"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gizmo_light.svg b/editor/icons/dark/icon_gizmo_light.svg
deleted file mode 100644
index c411d13dc7..0000000000
--- a/editor/icons/dark/icon_gizmo_light.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m64 6a40 40 0 0 0 -40 40 40 40 0 0 0 24 36.607v15.393a8 8 0 0 0 8 8h16a8 8 0 0 0 8 -8v-15.363a40 40 0 0 0 24 -36.637 40 40 0 0 0 -40 -40zm0 12a28 28 0 0 1 28 28 28 28 0 0 1 -28 28 28 28 0 0 1 -28 -28 28 28 0 0 1 28 -28zm-8 96v8h16v-8h-16z" fill="#f7f5cf"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gizmo_listener.svg b/editor/icons/dark/icon_gizmo_listener.svg
deleted file mode 100644
index adb6aebaec..0000000000
--- a/editor/icons/dark/icon_gizmo_listener.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -924.36)">
-<g transform="matrix(2 0 0 2 -16 -1040.4)">
-<path transform="matrix(.5 0 0 .5 8 982.36)" d="m48 8a40 39.998 0 0 0 -40 39.998h16a24 23.999 0 0 1 24 -23.998 24 23.999 0 0 1 24 23.998c0 13.999-4.33 18.859-9.1211 22.852-2.3955 1.9962-5.0363 3.5302-7.8125 5.5352-1.3881 1.0024-2.8661 2.126-4.3047 3.9414-1.4385 1.8152-2.7617 4.6719-2.7617 7.6719 0 10.221-2.5383 12.59-5.1172 14.137-2.5789 1.5472-6.8828 1.8594-10.883 1.8594v0.00195h-8v16h8v-0.00195c4 0 11.696 0.31158 19.117-4.1406 7.0602-4.236 12.198-13.279 12.695-26 0.1835-0.1636 0.14883-0.15489 0.62109-0.49609 1.7238-1.245 5.083-3.2112 8.6875-6.2148 7.209-6.0072 14.879-17.145 14.879-35.145a40 39.998 0 0 0 -40 -39.998zm63.426 8l-13.906 8.0312a48 47.998 0 0 1 6.4844 23.967 48 47.998 0 0 1 -6.4688 23.984l13.891 8.0137a64 63.997 0 0 0 0 -63.996z" fill="#f7f5cf"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gizmo_spatial_sample_player.svg b/editor/icons/dark/icon_gizmo_spatial_sample_player.svg
deleted file mode 100644
index d40fe230ac..0000000000
--- a/editor/icons/dark/icon_gizmo_spatial_sample_player.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m63.883 12.004a4.0004 4.0004 0 0 0 -2.7109 1.168l-30.828 30.83h-14.344a4.0004 4.0004 0 0 0 -4 4v32a4.0004 4.0004 0 0 0 4 4h14.344l30.828 30.828a4.0004 4.0004 0 0 0 6.8281 -2.8281v-96.002a4.0004 4.0004 0 0 0 -4.1172 -3.9961zm46.117 5.9961a6 6 0 0 0 -6 6v80a6 6 0 0 0 6 6 6 6 0 0 0 6 -6v-80a6 6 0 0 0 -6 -6zm-24 24a6 6 0 0 0 -6 6v32h0.34961a6 6 0 0 0 5.6504 4 6 6 0 0 0 5.6484 -4h0.35156v-32a6 6 0 0 0 -6 -6z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#f7f5cf" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gizmo_spatial_stream_player.svg b/editor/icons/dark/icon_gizmo_spatial_stream_player.svg
deleted file mode 100644
index 2cf3966364..0000000000
--- a/editor/icons/dark/icon_gizmo_spatial_stream_player.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -924.36)">
-<path d="m99.766 934.36a8.0008 8.0011 0 0 0 -1.9609 0.296l-56 16a8.0008 8.0011 0 0 0 -5.8047 7.6964v48.119a18 18.001 0 0 0 -2 -0.116 18 18.001 0 0 0 -18 18.001 18 18.001 0 0 0 18 18.001 18 18.001 0 0 0 17.875 -16.001h0.125v-2-59.963l40-11.43v37.517a18 18.001 0 0 0 -2 -0.124 18 18.001 0 0 0 -18 18.001 18 18.001 0 0 0 18 18 18 18.001 0 0 0 17.875 -16h0.125v-2-66.003a8.0008 8.0011 0 0 0 -8.2344 -7.9924z" color="#000000" color-rendering="auto" fill="#f7f5cf" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_godot.svg b/editor/icons/dark/icon_godot.svg
deleted file mode 100644
index 32a1eeb6ec..0000000000
--- a/editor/icons/dark/icon_godot.svg
+++ /dev/null
@@ -1,33 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="matrix(.017241 0 0 .017241 -.82759 1033.7)" stroke-width=".32031">
-<g transform="matrix(4.1626 0 0 -4.1626 919.24 771.67)">
-<path d="m0 0s-0.325 1.994-0.515 1.976l-36.182-3.491c-2.879-0.278-5.115-2.574-5.317-5.459l-0.994-14.247-27.992-1.997-1.904 12.912c-0.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-0.994 14.247c-0.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-0.187 0.018-0.324-1.978-0.511-1.978l-0.049-7.83 30.658-4.944 1.004-14.374c0.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c0.146-0.01 0.29-0.016 0.434-0.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c0.423-2.871 2.93-5.037 5.831-5.037 0.142 0 0.284 5e-3 0.423 0.015l38.556 2.75c2.911 0.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 104.7 525.91)">
-<path d="m0 0v-59.041c0.108-1e-3 0.216-5e-3 0.323-0.015l36.196-3.49c1.896-0.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c0.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c0.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c0.107 0.01 0.214 0.014 0.322 0.015v4.711l0.015 5e-3v54.325h0.134c4.795 6.12 9.232 12.569 13.487 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842 0.642-7.702 0.88-11.567 0.926v6e-3c-0.027 0-0.052-6e-3 -0.075-6e-3 -0.024 0-0.049 6e-3 -0.073 6e-3v-6e-3c-3.872-0.046-7.729-0.284-11.572-0.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17 0.216-8.34 0.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.253-6.88 8.693-13.329 13.487-19.449z" fill="#478cbf"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 784.07 817.24)">
-<path d="m0 0-1.121-16.063c-0.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-0.094-7e-3 -0.188-0.01-0.281-0.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-0.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936 0.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c0.015-3.498 0.06-7.33 0.06-8.093 0-34.374 43.605-50.896 97.781-51.086h0.133c54.176 0.19 97.766 16.712 97.766 51.086 0 0.777 0.047 4.593 0.063 8.093z" fill="#478cbf"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 389.21 625.67)">
-<path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 367.37 631.06)">
-<path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 511.99 724.74)">
-<path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 634.79 625.67)">
-<path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff"/>
-</g>
-<g transform="matrix(4.1626 0 0 -4.1626 656.64 631.06)">
-<path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042"/>
-</g>
-</g>
-<path d="m4 1041.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3zm0 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z"/>
-<path d="m12 1041.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3zm0 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z"/>
-<rect x="6" y="1043.4" width="4" height="1" ry="0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gradient.svg b/editor/icons/dark/icon_gradient.svg
deleted file mode 100644
index 0fac616d58..0000000000
--- a/editor/icons/dark/icon_gradient.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="10" x2="10" y1="1" y2="15" gradientUnits="userSpaceOnUse">
-<stop stop-color="#4f4f4f" offset="0"/>
-<stop stop-color="#4f4f4f" stop-opacity="0" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1c-0.55228 0-1 0.44772-1 1v12c0 0.55228 0.44772 1 1 1h12c0.55228 0 1-0.44772 1-1v-12c0-0.55228-0.44772-1-1-1z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gradient_texture.svg b/editor/icons/dark/icon_gradient_texture.svg
deleted file mode 100644
index d98f4c01a0..0000000000
--- a/editor/icons/dark/icon_gradient_texture.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="10" x2="10" y1="1" y2="15" gradientUnits="userSpaceOnUse">
-<stop stop-color="#4f4f4f" offset="0"/>
-<stop stop-color="#4f4f4f" stop-opacity="0" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1 -1v-12a1 1 0 0 0 -1 -1h-12zm1 2h10v8h-10v-8z" fill="url(#a)"/>
-<rect x="6" y="1043.4" width="2" height="1" fill="#4f4f4f"/>
-<rect x="6" y="1044.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="4" y="1045.4" width="2" height="1" fill="#4f4f4f"/>
-<rect x="8" y="1044.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="10" y="1044.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="8" y="1042.4" width="3" height="2" fill="#4f4f4f"/>
-<rect x="9" y="1041.4" width="1" height="1" fill="#4f4f4f"/>
-<rect x="5" y="1044.4" width="1" height="1" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_comment.svg b/editor/icons/dark/icon_graph_comment.svg
deleted file mode 100644
index f3faab0c54..0000000000
--- a/editor/icons/dark/icon_graph_comment.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m3 1v2h-2v2h2v4h-2v2h2v2h2v-2h4v2h2v-2h2v-2h-2v-4h2v-2h-2v-2h-2v2h-4v-2h-2zm2 4h4v4h-4v-4z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_cube_uniform.svg b/editor/icons/dark/icon_graph_cube_uniform.svg
deleted file mode 100644
index a7ef1499b5..0000000000
--- a/editor/icons/dark/icon_graph_cube_uniform.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m2 0c-1.1046 0-2 0.8954-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm4.9727 2a0.71438 0.71438 0 0 1 0.34766 0.074219l4.2852 2.1426a0.71438 0.71438 0 0 1 0.39453 0.64062v4.2852a0.71438 0.71438 0 0 1 -0.39453 0.63867l-4.2852 2.1426a0.71438 0.71438 0 0 1 -0.64062 0l-4.2852-2.1426a0.71438 0.71438 0 0 1 -0.39453 -0.63867v-4.2852a0.71438 0.71438 0 0 1 0.39453 -0.64062l4.2852-2.1426a0.71438 0.71438 0 0 1 0.29297 -0.074219zm0.027344 1.5137l-2.6895 1.3438 2.6895 1.3438 2.6895-1.3438-2.6895-1.3438zm-3.5723 2.498v2.6895l2.8574 1.4277v-2.6875l-2.8574-1.4297zm7.1445 0l-2.8574 1.4297v2.6875l2.8574-1.4277v-2.6895z" fill="#eac968"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_curve_map.svg b/editor/icons/dark/icon_graph_curve_map.svg
deleted file mode 100644
index a5a3184926..0000000000
--- a/editor/icons/dark/icon_graph_curve_map.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m2 1049.4c8 0 9 0 9-9" fill="none" stroke="#f6f6f6" stroke-linecap="round" stroke-width="2"/>
-<path transform="translate(0 1038.4)" d="m11 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-5 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#68d0ea"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_default_texture.svg b/editor/icons/dark/icon_graph_default_texture.svg
deleted file mode 100644
index 0a1a0e9673..0000000000
--- a/editor/icons/dark/icon_graph_default_texture.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m2 2v10h10v-10h-10zm9 2v5h-8l2-3 2 2 4-4z" fill="#eae068"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_edit.svg b/editor/icons/dark/icon_graph_edit.svg
deleted file mode 100644
index 0abd546971..0000000000
--- a/editor/icons/dark/icon_graph_edit.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -1 -1.7305v-5.8555l4.793 4.793 1.4141-1.4141-4.793-4.793h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm10.656 6.9297l-0.70703 0.70703 1.4141 1.4141 0.70703-0.70703-1.4141-1.4141zm-1.4141 1.4141l-3.8887 3.8887-0.35352 1.7676 1.7676-0.35352 3.8887-3.8887-1.4141-1.4141z" fill="#29d739"/>
-<ellipse cx="3" cy="1039.4" r="2" fill="#6e6e6e"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_input.svg b/editor/icons/dark/icon_graph_input.svg
deleted file mode 100644
index c5034ecd2c..0000000000
--- a/editor/icons/dark/icon_graph_input.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<circle cx="7" cy="1045.4" r="6" fill="#f6f6f6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_node.svg b/editor/icons/dark/icon_graph_node.svg
deleted file mode 100644
index bdeeefb8e4..0000000000
--- a/editor/icons/dark/icon_graph_node.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -1 -1.7305v-5.8555l4.0859 4.0859 1.4141-1.4141-4.0859-4.0859h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9.5 9a2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5 -2.5 2.5 2.5 0 0 0 -2.5 -2.5z" fill="#29d739"/>
-<ellipse cx="3" cy="1039.4" r="2" fill="#6e6e6e"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_rgb.svg b/editor/icons/dark/icon_graph_rgb.svg
deleted file mode 100644
index c7f2402382..0000000000
--- a/editor/icons/dark/icon_graph_rgb.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill-opacity=".39216">
-<path d="m7 1039.4a4 4 0 0 0 -4 4 4 4 0 0 0 0.03906 0.5195 4 4 0 0 0 -2.0391 3.4805 4 4 0 0 0 4 4 4 4 0 0 0 1.998 -0.541 4 4 0 0 0 2.002 0.541 4 4 0 0 0 4 -4 4 4 0 0 0 -2.0371 -3.4824 4 4 0 0 0 0.03711 -0.5176 4 4 0 0 0 -4 -4z" fill="#000000"/>
-<path d="m7 1040.4a3 3 0 0 0 -3 3 3 3 0 0 0 0.21094 1.1055 3 3 0 0 0 -2.2109 2.8945 3 3 0 0 0 3 3 3 3 0 0 0 2 -0.7676 3 3 0 0 0 2 0.7676 3 3 0 0 0 3 -3 3 3 0 0 0 -2.2148 -2.8906 3 3 0 0 0 0.21484 -1.1094 3 3 0 0 0 -3 -3z" fil#000000fff"/>
-<circle cx="7" cy="1043.4" r="3" fill="#f00"/>
-<circle cx="5" cy="1047.4" r="3" fill="#00f"/>
-<circle cx="9" cy="1047.4" r="3" fill="#0f0"/>
-<circle cx="7" cy="1043.4" r="3" fill="#f00"/>
-<circle cx="5" cy="1047.4" r="3" fill="#00f"/>
-<circle cx="9" cy="1047.4" r="3" fill="#0f0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_rgb_op.svg b/editor/icons/dark/icon_graph_rgb_op.svg
deleted file mode 100644
index 8ec7782b47..0000000000
--- a/editor/icons/dark/icon_graph_rgb_op.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m4 1050.4h6v-10h-6z" fill="#000000" fill-rule="evenodd" strok#000000fff" stroke-linejoin="round" stroke-width="2"/>
-<rect x="1" y="1041.4" width="2" height="2" #000000="#fff"/>
-<rect x="1" y="1047.4" width="2" height="#000000ill="#fff"/>
-<rect x="11" y="1044.4" width="2" heigh#000000" fill="#fff"/>
-<rect x="5" y="1041.4" width="4" height="2" fill="#ff4646" fill-opacity=".86275"/>
-<rect x="5" y="1044.4" width="4" height="2" fill="#46ff46" fill-opacity=".86275"/>
-<rect x="5" y="1047.4" width="4" height="2" fill="#4646ff" fill-opacity=".86275"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_rgb_uniform.svg b/editor/icons/dark/icon_graph_rgb_uniform.svg
deleted file mode 100644
index fb740429e5..0000000000
--- a/editor/icons/dark/icon_graph_rgb_uniform.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m2 1038.4c-1.1046 0-2 0.8954-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-10c0-1.1046-0.89543-2-2-2z" fill="#000000"/>
-<path transform="translate(0 1038.4)" d="m7 2a3 3 0 0 0 -3 3 3 3 0 0 0 0.21094 1.1055 3 3 0 0 0 -2.2109 2.8945 3 3 0 0 0 3 3 3 3 0 0 0 2 -0.76758 3 3 0 0 0 2 0.76758 3 3 0 0 0 3 -3 3 3 0 0 0 -2.2148 -2.8906 3 3 0 0 0 0.21484 -1.1094 3 3 0 0 0 -3 -3z" fil#000000fff" fill-opacity=".39216"/>
-<circle cx="7" cy="1043.4" r="3" fill="#f00" fill-opacity=".39216"/>
-<circle cx="5" cy="1047.4" r="3" fill="#00f" fill-opacity=".39216"/>
-<circle cx="9" cy="1047.4" r="3" fill="#0f0" fill-opacity=".39216"/>
-<circle cx="7" cy="1043.4" r="3" fill="#f00" fill-opacity=".39216"/>
-<circle cx="5" cy="1047.4" r="3" fill="#00f" fill-opacity=".39216"/>
-<circle cx="9" cy="1047.4" r="3" fill="#0f0" fill-opacity=".39216"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_scalar.svg b/editor/icons/dark/icon_graph_scalar.svg
deleted file mode 100644
index ba921a961c..0000000000
--- a/editor/icons/dark/icon_graph_scalar.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m6 2c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3h2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-5v2h5c1.6569 0 3-1.3431 3-3s-1.3431-3-3-3h-2a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1h5v-2h-5z" fill="#cf68ea"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_scalar_interp.svg b/editor/icons/dark/icon_graph_scalar_interp.svg
deleted file mode 100644
index edfbe36066..0000000000
--- a/editor/icons/dark/icon_graph_scalar_interp.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m2 1050.4 10-10" fill="none" stroke="#cf68ea" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_scalar_op.svg b/editor/icons/dark/icon_graph_scalar_op.svg
deleted file mode 100644
index 34f7d9b2b1..0000000000
--- a/editor/icons/dark/icon_graph_scalar_op.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#cf68ea">
-<path transform="translate(0 1038.4)" d="m4 1c-0.55226 1e-4 -0.99994 0.4477-1 1v10c5.52e-5 0.5523 0.44774 0.9999 1 1h6c0.55226-1e-4 0.99994-0.4477 1-1v-10c-5.5e-5 -0.5523-0.44774-0.9999-1-1zm1 3 4 3-4 3z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<rect x="1" y="1041.4" width="2" height="2"/>
-<rect x="1" y="1047.4" width="2" height="2"/>
-<rect x="11" y="1044.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_scalar_uniform.svg b/editor/icons/dark/icon_graph_scalar_uniform.svg
deleted file mode 100644
index d2ee2ec827..0000000000
--- a/editor/icons/dark/icon_graph_scalar_uniform.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m2 0a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10a2 2 0 0 0 -2 -2h-10zm4 2h5v2h-5a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h2c1.6569 0 3 1.3431 3 3s-1.3431 3-3 3h-5v-2h5a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-2c-1.6569 0-3-1.3431-3-3s1.3431-3 3-3z" fill="#cf68ea"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_scalars_to_vec.svg b/editor/icons/dark/icon_graph_scalars_to_vec.svg
deleted file mode 100644
index bd3bc0424a..0000000000
--- a/editor/icons/dark/icon_graph_scalars_to_vec.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="1" x2="13.014" y1="7" y2="7" gradientUnits="userSpaceOnUse">
-<stop stop-color="#cf68ea" offset="0"/>
-<stop stop-color="#b8ea68" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m1.9902 0.99023a1.0001 1.0001 0 0 0 -0.69727 1.7168l3.293 3.293h-2.5859a1.0001 1.0001 0 1 0 0 2h2.5859l-3.293 3.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.707-4.707h4.5859a1.0001 1.0001 0 1 0 0 -2h-4.5859l-4.707-4.707a1.0001 1.0001 0 0 0 -0.7168 -0.30273z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_texscreen.svg b/editor/icons/dark/icon_graph_texscreen.svg
deleted file mode 100644
index 6c26332203..0000000000
--- a/editor/icons/dark/icon_graph_texscreen.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m2 1041.4h10v8h-10z" fill="none" stroke="#f6f6f6" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<rect x="3" y="1042.4" width="8" height="1" fill="#f6f6f6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_texture_uniform.svg b/editor/icons/dark/icon_graph_texture_uniform.svg
deleted file mode 100644
index 9e72743432..0000000000
--- a/editor/icons/dark/icon_graph_texture_uniform.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m2 0c-1.1046 0-2 0.8954-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v10h-10v-10zm9 2l-4 4-2-2-2 3h8v-5z" fill="#eae068"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_time.svg b/editor/icons/dark/icon_graph_time.svg
deleted file mode 100644
index 6227b53c62..0000000000
--- a/editor/icons/dark/icon_graph_time.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#f6f6f6">
-<rect x="6" y="1042.4" width="2" height="4"/>
-<rect x="6" y="1044.4" width="4" height="2"/>
-<path transform="translate(0 1038.4)" d="m7 0a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5 -5 5 5 0 0 1 5 -5z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vec_dp.svg b/editor/icons/dark/icon_graph_vec_dp.svg
deleted file mode 100644
index 0b24b47895..0000000000
--- a/editor/icons/dark/icon_graph_vec_dp.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m1 1042.4 2 6 2-6" fill="none" stroke="#b8ea68" stroke-linejoin="round" stroke-width="2"/>
-<circle cx="7" cy="1046.4" r="1" fill="#b8ea68"/>
-<path d="m9 1042.4 2 6 2-6" fill="none" stroke="#b8ea68" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vec_interp.svg b/editor/icons/dark/icon_graph_vec_interp.svg
deleted file mode 100644
index a3df7ff93d..0000000000
--- a/editor/icons/dark/icon_graph_vec_interp.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m2 1050.4 10-10" fill="none" stroke="#b8ea68" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vec_length.svg b/editor/icons/dark/icon_graph_vec_length.svg
deleted file mode 100644
index cd2a39312a..0000000000
--- a/editor/icons/dark/icon_graph_vec_length.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<rect y="1039.4" width="2" height="12" fill="#b8ea68"/>
-<rect x="12" y="1039.4" width="2" height="12" fill="#b8ea68"/>
-<path d="m5 1043.4 2 5 2-5" fill="none" stroke="#b8ea68" stroke-linecap="square" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vec_op.svg b/editor/icons/dark/icon_graph_vec_op.svg
deleted file mode 100644
index 2792d63378..0000000000
--- a/editor/icons/dark/icon_graph_vec_op.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m4 1c-0.55226 1e-4 -0.99994 0.4477-1 1v1h-2v2h2v4h-2v2h2v1c5.52e-5 0.5523 0.44774 0.9999 1 1h6c0.55226-1e-4 0.99994-0.4477 1-1v-4h2v-2h-2v-4c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-6zm1 3l4 3-4 3v-6z" color="#000000" color-rendering="auto" fill="#b8ea68" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vec_scalar_op.svg b/editor/icons/dark/icon_graph_vec_scalar_op.svg
deleted file mode 100644
index effcb596a1..0000000000
--- a/editor/icons/dark/icon_graph_vec_scalar_op.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill-rule="evenodd" shape-rendering="auto">
-<path transform="translate(0 1038.4)" d="m3 7v2h-2v2h2v1c5.52e-5 0.5523 0.44774 0.9999 1 1h6c0.55226-1e-4 0.99994-0.4477 1-1v-4h2v-1h-4l-4 3v-3h-2z" color="#000000" color-rendering="auto" fill="#cf68ea" image-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m3 1045.4v-2h-2v-2h2v-1c5.52e-5 -0.5523 0.44774-0.9999 1-1h6c0.55226 1e-4 0.99994 0.4477 1 1v4h2v1h-4l-4-3v3h-2z" color="#000000" color-rendering="auto" fill="#b8ea68" image-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vec_to_scalars.svg b/editor/icons/dark/icon_graph_vec_to_scalars.svg
deleted file mode 100644
index 2ecacb8434..0000000000
--- a/editor/icons/dark/icon_graph_vec_to_scalars.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="1" x2="13.014" y1="7" y2="7" gradientTransform="matrix(-1 0 0 1 14 1038.4)" gradientUnits="userSpaceOnUse">
-<stop stop-color="#cf68ea" offset="0"/>
-<stop stop-color="#b8ea68" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1038.4)">
-<path d="m12.01 1039.4a1.0001 1.0001 0 0 1 0.69726 1.7168l-3.293 3.293h2.5859a1.0001 1.0001 0 1 1 0 2h-2.5859l3.293 3.293a1.0001 1.0001 0 1 1 -1.4141 1.414l-4.707-4.707h-4.5859a1.0001 1.0001 0 1 1 0 -2h4.5859l4.707-4.707a1.0001 1.0001 0 0 1 0.7168 -0.3028z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vecs_to_xform.svg b/editor/icons/dark/icon_graph_vecs_to_xform.svg
deleted file mode 100644
index 8bd533fbf0..0000000000
--- a/editor/icons/dark/icon_graph_vecs_to_xform.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="1" x2="13.014" y1="7" y2="7" gradientTransform="translate(.00074682 1038.4)" gradientUnits="userSpaceOnUse">
-<stop stop-color="#b8ea68" offset="0"/>
-<stop stop-color="#e3383d" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1038.4)">
-<path d="m1.991 1039.4a1.0001 1.0001 0 0 0 -0.69726 1.7168l3.293 3.293h-2.5859a1.0001 1.0001 0 1 0 0 2h2.5859l-3.293 3.293a1.0001 1.0001 0 1 0 1.4141 1.414l4.707-4.707h4.5859a1.0001 1.0001 0 1 0 0 -2h-4.5859l-4.707-4.707a1.0001 1.0001 0 0 0 -0.7168 -0.3028z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vector.svg b/editor/icons/dark/icon_graph_vector.svg
deleted file mode 100644
index 81772fa4f5..0000000000
--- a/editor/icons/dark/icon_graph_vector.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m8 1038.4v2h-5v2h5v2l3-3zm-3.6562 5.6289-1.7148 1.0293 0.51367 0.8574 3 5c0.3885 0.647 1.3263 0.647 1.7148 0l3-5 0.51367-0.8574-1.7148-1.0293-0.51367 0.8574-2.1426 3.5703-2.1426-3.5703z" color="#000000" color-rendering="auto" fill="#b8ea68" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_vector_uniform.svg b/editor/icons/dark/icon_graph_vector_uniform.svg
deleted file mode 100644
index 66f31bf5dd..0000000000
--- a/editor/icons/dark/icon_graph_vector_uniform.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m2 0c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm6 0 3 3-3 3v-2h-5v-2h5zm-3.6562 5.6289 0.51367 0.85742 2.1426 3.5703 2.1426-3.5703 0.51367-0.85742l1.7148 1.0293-0.51367 0.85742-3 5c-0.3885 0.64706-1.3263 0.64706-1.7148 0l-3-5-0.51367-0.85742z" fill="#b8ea68"/>
-<path transform="translate(0 1038.4)" d="m23 0v2h-5v2h5v2l3-3zm-3.6562 5.6289-1.7148 1.0293 0.51367 0.85742 3 5c0.3885 0.64706 1.3263 0.64706 1.7148 0l3-5 0.51367-0.85742-1.7148-1.0293-0.51367 0.85742-2.1426 3.5703-2.1426-3.5703z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform.svg b/editor/icons/dark/icon_graph_xform.svg
deleted file mode 100644
index 0554285612..0000000000
--- a/editor/icons/dark/icon_graph_xform.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<rect x="1" y="1039.4" width="1" height="12" fill="#e3383d"/>
-<rect x="1" y="1039.4" width="3" height="1" fill="#e3383d"/>
-<rect x="1" y="1050.4" width="3" height="1" fill="#e3383d"/>
-<rect x="10" y="1050.4" width="3" height="1" fill="#e3383d"/>
-<rect x="10" y="1039.4" width="3" height="1" fill="#e3383d"/>
-<rect x="12" y="1039.4" width="1" height="12" fill="#e3383d"/>
-<path d="m4 1049.4v-7l3 3 3-3v7" fill="none" stroke="#e3383d" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform_mult.svg b/editor/icons/dark/icon_graph_xform_mult.svg
deleted file mode 100644
index 0e2da7f7c0..0000000000
--- a/editor/icons/dark/icon_graph_xform_mult.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m1 1049.4v-7l2 3 2-3v7" fill="none" stroke="#e3383d" stroke-linejoin="round" stroke-width="2"/>
-<path d="m9 1049.4v-7l2 3 2-3v7" fill="none" stroke="#e3383d" stroke-linejoin="round" stroke-width="2"/>
-<circle cx="7" cy="1045.4" r="1" fill="#e3383d"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform_scalar_func.svg b/editor/icons/dark/icon_graph_xform_scalar_func.svg
deleted file mode 100644
index 350d9e98d7..0000000000
--- a/editor/icons/dark/icon_graph_xform_scalar_func.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#cf68ea">
-<rect x="6" y="1042.4" width="2" height="5"/>
-<path transform="translate(0 1038.4)" d="m9.0703 1a3 3 0 0 0 -1.5703 0.40234 3 3 0 0 0 -1.5 2.5977h2a1 1 0 0 1 1 -1 1 1 0 0 1 1 1h2a3 3 0 0 0 -1.5 -2.5977 3 3 0 0 0 -1.4297 -0.40234z"/>
-<rect x="10" y="1042.4" width="2" height="1"/>
-<path transform="translate(0 1038.4)" d="m2 10a3 3 0 0 0 1.5 2.5977 3 3 0 0 0 3 0 3 3 0 0 0 1.5 -2.5977h-2a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1h-2z"/>
-<rect transform="scale(1,-1)" x="6" y="-1048.4" width="2" height="1"/>
-<rect x="4" y="1044.4" width="6" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform_to_vecs.svg b/editor/icons/dark/icon_graph_xform_to_vecs.svg
deleted file mode 100644
index 6fb5953b95..0000000000
--- a/editor/icons/dark/icon_graph_xform_to_vecs.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="1" x2="13.014" y1="7" y2="7" gradientTransform="matrix(-1 0 0 1 14 1038.4)" gradientUnits="userSpaceOnUse">
-<stop stop-color="#b8ea68" offset="0"/>
-<stop stop-color="#e3383d" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1038.4)">
-<path d="m12.01 1039.4a1.0001 1.0001 0 0 1 0.69726 1.7168l-3.293 3.293h2.5859a1.0001 1.0001 0 1 1 0 2h-2.5859l3.293 3.293a1.0001 1.0001 0 1 1 -1.4141 1.414l-4.707-4.707h-4.5859a1.0001 1.0001 0 1 1 0 -2h4.5859l4.707-4.707a1.0001 1.0001 0 0 1 0.7168 -0.3028z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#a)" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform_uniform.svg b/editor/icons/dark/icon_graph_xform_uniform.svg
deleted file mode 100644
index 9fd8eca5b0..0000000000
--- a/editor/icons/dark/icon_graph_xform_uniform.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m2 0c-1.1046 0-2 0.8954-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm-1 1h1 2v1h-2v10h2v1h-2-1v-1-10-1zm9 0h3v11 1h-3v-1h2v-10h-2v-1zm-0.029297 2a1.0001 1.0001 0 0 1 1.0293 1v7h-2v-4.5859l-1.293 1.293a1.0001 1.0001 0 0 1 -1.4141 0l-1.293-1.293v4.5859h-2v-7a1.0001 1.0001 0 0 1 0.98438 -0.99805 1.0001 1.0001 0 0 1 0.72266 0.29102l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 0.67773 -0.29297z" fill="#e3383d"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform_vec_func.svg b/editor/icons/dark/icon_graph_xform_vec_func.svg
deleted file mode 100644
index 29bff80cd5..0000000000
--- a/editor/icons/dark/icon_graph_xform_vec_func.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#b8ea68">
-<rect x="6" y="1042.4" width="2" height="5"/>
-<path transform="translate(0 1038.4)" d="m9.0703 1a3 3 0 0 0 -1.5703 0.40234 3 3 0 0 0 -1.5 2.5977h2a1 1 0 0 1 1 -1 1 1 0 0 1 1 1h2a3 3 0 0 0 -1.5 -2.5977 3 3 0 0 0 -1.4297 -0.40234z"/>
-<rect x="10" y="1042.4" width="2" height="1"/>
-<path transform="translate(0 1038.4)" d="m2 10a3 3 0 0 0 1.5 2.5977 3 3 0 0 0 3 0 3 3 0 0 0 1.5 -2.5977h-2a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1h-2z"/>
-<rect transform="scale(1,-1)" x="6" y="-1048.4" width="2" height="1"/>
-<rect x="4" y="1044.4" width="6" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform_vec_imult.svg b/editor/icons/dark/icon_graph_xform_vec_imult.svg
deleted file mode 100644
index 39d0ea4646..0000000000
--- a/editor/icons/dark/icon_graph_xform_vec_imult.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m1 1042.4 2 6 2-6" fill="none" stroke="#b8ea68" stroke-linejoin="round" stroke-width="2"/>
-<circle cx="7" cy="1046.4" r="1" fill="#b8ea68"/>
-<path d="m9 1049.4v-7l2 3 2-3v7" fill="none" stroke="#e3383d" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_graph_xform_vec_mult.svg b/editor/icons/dark/icon_graph_xform_vec_mult.svg
deleted file mode 100644
index 5f59622855..0000000000
--- a/editor/icons/dark/icon_graph_xform_vec_mult.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path d="m9 1042.4 2 6 2-6" fill="none" stroke="#b8ea68" stroke-linejoin="round" stroke-width="2"/>
-<circle cx="7" cy="1046.4" r="1" fill="#b8ea68"/>
-<path d="m1 1049.4v-7l2 3 2-3v7" fill="none" stroke="#e3383d" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_grid.svg b/editor/icons/dark/icon_grid.svg
deleted file mode 100644
index b4c7be4678..0000000000
--- a/editor/icons/dark/icon_grid.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 10 2h2 12v-2-12h-12-2zm2 2h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_grid_container.svg b/editor/icons/dark/icon_grid_container.svg
deleted file mode 100644
index c16949a03a..0000000000
--- a/editor/icons/dark/icon_grid_container.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_grid_map.svg b/editor/icons/dark/icon_grid_map.svg
deleted file mode 100644
index a84cdf9994..0000000000
--- a/editor/icons/dark/icon_grid_map.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1-6 3v8l6 3 6-3v-2l-2-1-4 2-2-1v-4l2-1v-2l2-1zm4 2-2 1v2l2 1 2-1v-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_groove_joint_2d.svg b/editor/icons/dark/icon_groove_joint_2d.svg
deleted file mode 100644
index a84c735300..0000000000
--- a/editor/icons/dark/icon_groove_joint_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m15 1037.4h-5v6h-5v2h5v6h5zm-7 0h-7v14h7v-4h-5v-6h5z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_group.svg b/editor/icons/dark/icon_group.svg
deleted file mode 100644
index 324de52572..0000000000
--- a/editor/icons/dark/icon_group.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v6h-6v8h8v-6h6v-8zm2 2h4v4h-4z" fill="#4f4f4f" fill-opacity=".39216"/>
-<path transform="translate(0 1036.4)" d="m1 1v2c0 2.34e-5 0.446 0 1 0s1 2.34e-5 1 0v-2c0-2.341e-5 -0.446 0-1 0s-1-2.341e-5 -1 0zm12 0v2c0 2.34e-5 0.446 0 1 0s1 2.34e-5 1 0v-2c0-2.341e-5 -0.446 0-1 0s-1-2.341e-5 -1 0zm-12 12v2c0 2.3e-5 0.446 0 1 0s1 2.3e-5 1 0v-2c0-2.3e-5 -0.446 0-1 0s-1-2.3e-5 -1 0zm12 0v2c0 2.3e-5 0.446 0 1 0s1 2.3e-5 1 0v-2c0-2.3e-5 -0.446 0-1 0s-1-2.3e-5 -1 0z" fill="#000000"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_groups.svg b/editor/icons/dark/icon_groups.svg
deleted file mode 100644
index cb94b0e4d3..0000000000
--- a/editor/icons/dark/icon_groups.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="1" y="1040.4" width="14" height="8" fill="none" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-<ellipse cx="5" cy="1044.4" rx="2" ry="2" fill="#4f4f4f"/>
-<ellipse cx="11" cy="1044.4" rx="2" ry="2" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_gui_close.svg b/editor/icons/dark/icon_gui_close.svg
deleted file mode 100644
index 822c59653e..0000000000
--- a/editor/icons/dark/icon_gui_close.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3.7578 2.3438l-1.4141 1.4141 4.2422 4.2422-4.2422 4.2422 1.4141 1.4141 4.2422-4.2422 4.2422 4.2422 1.4141-1.4141-4.2422-4.2422 4.2422-4.2422-1.4141-1.4141-4.2422 4.2422-4.2422-4.2422z" fill="#000000" fill-opacity=".89804"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_h_box_container.svg b/editor/icons/dark/icon_h_box_container.svg
deleted file mode 100644
index b42fb42236..0000000000
--- a/editor/icons/dark/icon_h_box_container.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z"/>
-<rect x="5" y="1039.4" width="2" height="10"/>
-<rect x="9" y="1039.4" width="2" height="10"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_h_button_array.svg b/editor/icons/dark/icon_h_button_array.svg
deleted file mode 100644
index 99888a9c02..0000000000
--- a/editor/icons/dark/icon_h_button_array.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 1v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328h-2zm8 4v2h-2v2h2v2h2v-2h2v-2h-2v-2h-2zm-8.5 4c-0.831 0-1.5 0.669-1.5 1.5v0.5 1h-1v2h8v-2h-1v-1-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_h_scroll_bar.svg b/editor/icons/dark/icon_h_scroll_bar.svg
deleted file mode 100644
index 69da81e86f..0000000000
--- a/editor/icons/dark/icon_h_scroll_bar.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m15 1041.4c0-1.108-0.892-2-2-2h-10c-1.108 0-2 0.892-2 2v6c0 1.108 0.892 2 2 2h10c1.108 0 2-0.892 2-2zm-1 2.9883a1.0001 1.0001 0 0 1 -0.168 0.5664l-2 3a1.0001 1.0001 0 1 1 -1.664 -1.1094l1.6289-2.4453-1.6289-2.4453a1.0001 1.0001 0 1 1 1.664 -1.1094l2 3a1.0001 1.0001 0 0 1 0.168 0.543zm-7.9922-2.9981a1.0001 1.0001 0 0 1 -0.1758 0.5645l-1.6308 2.4453 1.6308 2.4453a1.0001 1.0001 0 1 1 -1.664 1.1094l-2-3a1.0001 1.0001 0 0 1 0 -1.1094l2-3a1.0001 1.0001 0 0 1 1.8398 0.5449z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_h_separator.svg b/editor/icons/dark/icon_h_separator.svg
deleted file mode 100644
index 8b6f12a5aa..0000000000
--- a/editor/icons/dark/icon_h_separator.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<rect x="5" y="1038.4" width="6" height="3"/>
-<rect transform="matrix(0,-1,-1,0,0,0)" x="-1045.4" y="-15" width="2" height="14"/>
-<rect x="5" y="1047.4" width="6" height="3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_h_slider.svg b/editor/icons/dark/icon_h_slider.svg
deleted file mode 100644
index 8c34f93206..0000000000
--- a/editor/icons/dark/icon_h_slider.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 3c-0.55228 0-1 0.44772-1 1v2c0 0.55228 0.44772 1 1 1s1-0.44772 1-1v-2c0-0.55228-0.44772-1-1-1zm12 0c-0.55228 0-1 0.44772-1 1v2c0 0.55228 0.44772 1 1 1s1-0.44772 1-1v-2c0-0.55228-0.44772-1-1-1zm-6 1c-0.55228 0-1 0.44772-1 1s0.44772 1 1 1 1-0.44772 1-1-0.44772-1-1-1zm5 5c-1.1046 0-2 0.89543-2 2 0 1.1046 0.89543 2 2 2 1.0099-3.37e-4 1.8611-0.75351 1.9844-1.7559 0.04003-0.16104 0.03936-0.32952-2e-3 -0.49024-0.12404-1.0008-0.97388-1.7527-1.9824-1.7539zm-11 1c-1.3523-0.019125-1.3523 2.0191 0 2h7.1309c-0.085635-0.32648-0.1296-0.66248-0.13086-1 0.00189-0.3376 0.046518-0.67361 0.13281-1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#29d739" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_h_split_container.svg b/editor/icons/dark/icon_h_split_container.svg
deleted file mode 100644
index 7ca7c5567f..0000000000
--- a/editor/icons/dark/icon_h_split_container.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z"/>
-<rect x="7" y="1039.4" width="2" height="10"/>
-<path d="m9 1042.4v4l2-2z"/>
-<path d="m7 1042.4-2 2 2 2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_h_t_t_p_request.svg b/editor/icons/dark/icon_h_t_t_p_request.svg
deleted file mode 100644
index 115d88bae8..0000000000
--- a/editor/icons/dark/icon_h_t_t_p_request.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m1 10v2 1 2h1v-2h1v2h1v-5h-1v2h-1v-2h-1zm4 0v1h1v4h1v-4h1v-1h-3zm4 0v1h1v4h1v-4h1v-1h-3zm4 0v2 1 2h1v-2h1 1v-1-2h-2-1zm1 1h1v1h-1v-1z"/>
-<path transform="translate(0 1036.4)" d="m4 1l-3 4h2v3h2v-3h2l-3-4zm7 0v3h-2l3 4 3-4h-2v-3h-2z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_headphones.svg b/editor/icons/dark/icon_headphones.svg
deleted file mode 100644
index f0c0fd8812..0000000000
--- a/editor/icons/dark/icon_headphones.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m1 1046.4v3h2v2h2v-5h-4z"/>
-<path d="m11 1046.4v5h2v-2h2v-3h-4z"/>
-<path d="m8 1037.4a7 7 0 0 0 -7 7h2a5 5 0 0 1 5 -5 5 5 0 0 1 5 5h2a7 7 0 0 0 -7 -7z"/>
-<rect x="1" y="1044.4" width="2" height="2"/>
-<rect x="13" y="1044.4" width="2" height="2"/>
-<circle cx="3" cy="1049.4" r="2"/>
-<circle transform="scale(-1,1)" cx="-13" cy="1049.4" r="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_help.svg b/editor/icons/dark/icon_help.svg
deleted file mode 100644
index 3c294f92b6..0000000000
--- a/editor/icons/dark/icon_help.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5.0293 1c-0.99969-0.010925-2.0096 0.31165-3.0293 1v7c2.0172-1.3529 4.0167-1.3136 6 0 1.9833-1.3136 3.9828-1.3529 6 0v-7c-1.0197-0.68835-2.0296-1.0109-3.0293-1-0.6613 0.007227-1.3175 0.1735-1.9707 0.46289v4.5371h-1v-4c-0.98156-0.64465-1.971-0.98908-2.9707-1zm-5.0293 9v6h2a3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3h-2zm5 3a3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3 3 3 0 0 0 -3 3zm6 0a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1h1v-2h-1a3 3 0 0 0 -3 3zm-9-1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v-2zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#4f4f4f" fill-opacity=".58824" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_help_search.svg b/editor/icons/dark/icon_help_search.svg
deleted file mode 100644
index 2fea4e2b7d..0000000000
--- a/editor/icons/dark/icon_help_search.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" stroke-width="2">
-<path transform="translate(0 1036.4)" d="m0 10v6h2c1.6569 0 3-1.3431 3-3s-1.3431-3-3-3zm5 3c0 1.6569 1.3431 3 3 3s3-1.3431 3-3-1.3431-3-3-3-3 1.3431-3 3zm6 0c0 1.6569 1.3431 3 3 3h1v-2h-1c-0.55228-1e-5 -0.99999-0.44772-1-1 1e-5 -0.55228 0.44772-0.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm-9-1c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1zm6 0c0.55228 1e-5 0.99999 0.44772 1 1-9.6e-6 0.55228-0.44772 0.99999-1 1-0.55228-1e-5 -0.99999-0.44772-1-1 9.6e-6 -0.55228 0.44772-0.99999 1-1z" fill="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549"/>
-<path d="m9 1036.4a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549"/>
-<path d="m7 1042.4-3 3" fill="none" stroke="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_hidden.svg b/editor/icons/dark/icon_hidden.svg
deleted file mode 100644
index e726d8863e..0000000000
--- a/editor/icons/dark/icon_hidden.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2.9609 7.7266l-1.9219 0.54883c0.31999 1.12 0.8236 2.0593 1.4316 2.8398l-0.83398 0.83398 1.4141 1.4141 0.84375-0.84375c0.98585 0.74762 2.0766 1.2067 3.1055 1.3867v1.0938h2v-1.0938c1.0288-0.17998 2.1196-0.6391 3.1055-1.3867l0.84375 0.84375 1.4141-1.4141-0.83398-0.83398c0.60804-0.78055 1.1117-1.7199 1.4316-2.8398l-1.9219-0.54883c-0.8756 3.0646-3.5391 4.2734-5.0391 4.2734s-4.1635-1.2088-5.0391-4.2734z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_hinge_joint.svg b/editor/icons/dark/icon_hinge_joint.svg
deleted file mode 100644
index b7eddfe22b..0000000000
--- a/editor/icons/dark/icon_hinge_joint.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.2832 1.3281a1.0001 1.0001 0 0 0 -0.88086 0.51172l-3.6895 6.3906c0.40599-0.13877 0.83411-0.23047 1.2871-0.23047 0.37043 0 0.72206 0.067873 1.0625 0.16211l3.0723-5.3223a1.0001 1.0001 0 0 0 -0.85156 -1.5117zm-3.2832 7.6719a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h10a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-7.1738a3 3 0 0 0 0.17383 -1 3 3 0 0 0 -3 -3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_history.svg b/editor/icons/dark/icon_history.svg
deleted file mode 100644
index 03c0f199d4..0000000000
--- a/editor/icons/dark/icon_history.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4 -4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6z"/>
-<path transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)" d="m4.118 1048.3-1.6771-0.9683-1.6771-0.9682 1.6771-0.9683 1.6771-0.9682-1e-7 1.9365z"/>
-<rect x="8" y="1041.4" width="2" height="4"/>
-<rect x="8" y="1043.4" width="4" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_hsize.svg b/editor/icons/dark/icon_hsize.svg
deleted file mode 100644
index 0b5e1c15bb..0000000000
--- a/editor/icons/dark/icon_hsize.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 7v-2l-3 3 3 3v-2h8v2l3-3-3-3v2z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_image.svg b/editor/icons/dark/icon_image.svg
deleted file mode 100644
index 6a01dd6138..0000000000
--- a/editor/icons/dark/icon_image.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1 -1v-12a1 1 0 0 0 -1 -1h-12zm1 2h10v8h-10v-8zm6 2l-1.5 2.5-0.70117 1.168-0.099609-0.16797-0.89844-1.5-0.90039 1.5-0.90039 1.5h1.8008 0.19922 1.5996 1.4004 3l-1.5-2.5-1.5-2.5z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_image_texture.svg b/editor/icons/dark/icon_image_texture.svg
deleted file mode 100644
index 8805df28b9..0000000000
--- a/editor/icons/dark/icon_image_texture.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1 -1v-12a1 1 0 0 0 -1 -1h-12zm1 2h10v8h-10v-8zm6 2v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1h-1z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_immediate_geometry.svg b/editor/icons/dark/icon_immediate_geometry.svg
deleted file mode 100644
index 60b0f8ea36..0000000000
--- a/editor/icons/dark/icon_immediate_geometry.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2.9208 1046.4c-0.26373 0.3-0.4204 0.7296-0.4204 1.2383 0 1.6277-3.1381-0.1781-0.33757 2.6703 0.88382 0.899 2.6544 0.6701 3.5382-0.2288 0.88384-0.899 0.88382-2.3565 0-3.2554-1.1002-1.1191-2.2001-1.0845-2.7803-0.4244zm2.3802-1.6103 2.4005 2.4416 6.8014-6.9177c0.66286-0.6742 0.66286-1.7673 0-2.4415-0.66288-0.6741-1.7376-0.6741-2.4005 0z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_import_check.svg b/editor/icons/dark/icon_import_check.svg
deleted file mode 100644
index 758572899a..0000000000
--- a/editor/icons/dark/icon_import_check.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1044.4 4 4 8-8" fill="none" stroke="#00f010" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_import_fail.svg b/editor/icons/dark/icon_import_fail.svg
deleted file mode 100644
index f7179e1e90..0000000000
--- a/editor/icons/dark/icon_import_fail.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -0.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141 -1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -0.72656 -1.7148 1.0001 1.0001 0 0 0 -0.6875 0.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -0.7168 -0.30273z" color="#000000" color-rendering="auto" fill="#ff4040" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_instance.svg b/editor/icons/dark/icon_instance.svg
deleted file mode 100644
index 46446b617f..0000000000
--- a/editor/icons/dark/icon_instance.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m5 1047.4 6-6" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-<path transform="translate(0 1036.4)" d="m11 1c-2.1973 0-4 1.8027-4 4 0 0.35477 0.062329 0.69321 0.15039 1.0215l2.3945-2.3945c0.36302-0.38506 0.87563-0.62695 1.4551-0.62695 1.1164 0 2 0.8836 2 2 0 0.57388-0.23667 1.0829-0.61523 1.4453l-2.4043 2.4043c0.32773 0.087749 0.66541 0.15039 1.0195 0.15039 2.1973 0 4-1.8027 4-4s-1.8027-4-4-4zm-6 6c-2.1973 0-4 1.8027-4 4s1.8027 4 4 4 4-1.8027 4-4c0-0.35412-0.062641-0.6918-0.15039-1.0195l-2.4043 2.4043c-0.36245 0.37857-0.87143 0.61523-1.4453 0.61523-1.1164 0-2-0.8836-2-2 0-0.57944 0.24189-1.0921 0.62695-1.4551l2.3945-2.3945c-0.32827-0.088062-0.66671-0.15039-1.0215-0.15039z" color="#000000" color-rendering="auto" fill="#4f4f4f" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_instance_options.svg b/editor/icons/dark/icon_instance_options.svg
deleted file mode 100644
index 50444dab54..0000000000
--- a/editor/icons/dark/icon_instance_options.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m1 7v6c0 1.1046 0.89543 2 2 2h12v-8h-14zm4 2h6l-3 4-3-4z"/>
-<path d="m0.71129 1040.4 0.28871 1.9791l2.2438-0.3273-0.81826-1.9018-1.7143 0.25zm3.6933-0.5387 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5775 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5774 0.81826 1.9018 1.7143-0.25-0.28871-1.9791-2.2438 0.3273z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_integer.svg b/editor/icons/dark/icon_integer.svg
deleted file mode 100644
index bcd952f635..0000000000
--- a/editor/icons/dark/icon_integer.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#cf68ea">
-<rect x="6" y="1040.4" width="2" height="10"/>
-<rect x="4" y="1039.4" width="6" height="2"/>
-<rect x="4" y="1049.4" width="6" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_interp_cubic.svg b/editor/icons/dark/icon_interp_cubic.svg
deleted file mode 100644
index 35726ce1e9..0000000000
--- a/editor/icons/dark/icon_interp_cubic.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path d="m2 1050.4c3 0 3-4 6-4s3 4 6 4" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_interp_linear.svg b/editor/icons/dark/icon_interp_linear.svg
deleted file mode 100644
index adc3d8212b..0000000000
--- a/editor/icons/dark/icon_interp_linear.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path d="m2 1050.4 6-4 6 4" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_interp_raw.svg b/editor/icons/dark/icon_interp_raw.svg
deleted file mode 100644
index 46b8b86467..0000000000
--- a/editor/icons/dark/icon_interp_raw.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path d="m2 1050.4h3v-4h6v4h3" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_interp_wrap_clamp.svg b/editor/icons/dark/icon_interp_wrap_clamp.svg
deleted file mode 100644
index 699266a7c0..0000000000
--- a/editor/icons/dark/icon_interp_wrap_clamp.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect x="1" y="1045.4" width="2" height="6" rx="1.7383e-5" ry="1.7383e-5" fill="#4f4f4f"/>
-<rect x="13" y="1045.4" width="2" height="6" rx="1.7383e-5" ry="1.7383e-5" fill="#4f4f4f"/>
-<path d="m5 1048.4h6" fill="none" stroke="#4f4f4f" stroke-width="2"/>
-<path d="m6 1046.4-2 2 2 2" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m10 1046.4 2 2-2 2" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_interp_wrap_loop.svg b/editor/icons/dark/icon_interp_wrap_loop.svg
deleted file mode 100644
index a537d02cb4..0000000000
--- a/editor/icons/dark/icon_interp_wrap_loop.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)" fill="#4f4f4f">
-<path transform="translate(0 1044.4)" d="m12 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3z"/>
-<path transform="translate(0 1044.4)" d="m4 1a3 3 0 0 0 -3 3 3 3 0 0 0 3 3v-2a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1v-2z"/>
-<rect x="9" y="1045.4" width="3" height="2" rx="6.5185e-6" ry="1.7383e-5"/>
-<rect x="4" y="1049.4" width="3" height="2" rx="6.5185e-6" ry="1.7383e-5"/>
-<path d="m7 1048.4v4l3-2z" fill-rule="evenodd"/>
-<path d="m9 1044.4v4l-3-2z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_interpolated_camera.svg b/editor/icons/dark/icon_interpolated_camera.svg
deleted file mode 100644
index 4627633dde..0000000000
--- a/editor/icons/dark/icon_interpolated_camera.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m9 0a3 3 0 0 0 -2.9883 2.7773 3 3 0 0 0 -2.0117 -0.77734 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8242v2.1758c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1 -2.2305 3 3 0 0 0 -3 -3zm-6 12v4h1v-4h-1zm3 0v4h1v-1h1a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1-1zm5 0a1 1 0 0 0 -1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-1zm-4 1h1v1h-1v-1zm4 0h1v2h-1v-2z" fill="#ff5f5f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_invalid_key.svg b/editor/icons/dark/icon_invalid_key.svg
deleted file mode 100644
index 0ff88aa9ee..0000000000
--- a/editor/icons/dark/icon_invalid_key.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path d="m0.46447 1046.2 2.1213 2.1213-2.1213 2.1213 1.4142 1.4142l2.1213-2.1213 2.1213 2.1213 1.4142-1.4142-2.1213-2.1213 2.1213-2.1213-1.4142-1.4142-2.1213 2.1213-2.1213-2.1213-1.4142 1.4142z" fill="#ff4040"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_inverse_kinematics.svg b/editor/icons/dark/icon_inverse_kinematics.svg
deleted file mode 100644
index 724d98a6f0..0000000000
--- a/editor/icons/dark/icon_inverse_kinematics.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m3 1039.4v12" fill="none" stroke="#ff5f5f" stroke-width="2"/>
-<circle cx="3" cy="1039.4" r="2" fill="#ff5f5f"/>
-<path d="m10 1039.4h-7" fill="#ff5f5f" fill-rule="evenodd" stroke="#ff5f5f" stroke-width="2"/>
-<circle cx="11" cy="1039.4" r="2" fill="#ff5f5f"/>
-<rect x="8" y="1044.4" width="6" height="2" fill="#ff5f5f"/>
-<path d="m11 1039.4v6" fill="none" stroke="#ff5f5f" stroke-width="2"/>
-<path d="m10 1046.4v4l-3-2 1-2z" fill="#ff5f5f" fill-rule="evenodd"/>
-<path d="m12 1046.4v4l3-2-1-2z" fill="#ff5f5f" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_item_list.svg b/editor/icons/dark/icon_item_list.svg
deleted file mode 100644
index d5de68a6bf..0000000000
--- a/editor/icons/dark/icon_item_list.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z"/>
-<rect x="4" y="1040.4" width="2" height="2"/>
-<rect x="7" y="1040.4" width="2" height="2"/>
-<rect x="10" y="1040.4" width="2" height="2"/>
-<rect x="4" y="1043.4" width="2" height="2"/>
-<rect x="7" y="1043.4" width="2" height="2"/>
-<rect x="10" y="1043.4" width="2" height="2"/>
-<rect x="4" y="1046.4" width="2" height="2"/>
-<rect x="7" y="1046.4" width="2" height="2"/>
-<rect x="10" y="1046.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_joy_axis.svg b/editor/icons/dark/icon_joy_axis.svg
deleted file mode 100644
index e1d9171dbe..0000000000
--- a/editor/icons/dark/icon_joy_axis.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="27" y="1038.4" width="7" height="14" fill="#000000" fill-opacity=".99608"/>
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h12v-14h-12zm4 2h2a1 1 0 0 1 1 1v2h2a1 1 0 0 1 1 1v2a1 1 0 0 1 -1 1h-2v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-2h-2a1 1 0 0 1 -1 -1v-2a1 1 0 0 1 1 -1h2v-2a1 1 0 0 1 1 -1z" fil#4f4f4f0e0" fill-opacity=".99608"/>
-<circle cx="8" cy="1044.4" r="1" fil#4f4f4f0e0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_joy_button.svg b/editor/icons/dark/icon_joy_button.svg
deleted file mode 100644
index fd7ca29b77..0000000000
--- a/editor/icons/dark/icon_joy_button.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-opacity=".99608">
-<rect x="27" y="1038.4" width="7" height="14" fill="#000000"/>
-<path transform="translate(0 1036.4)" d="m1 1v14h12c1.1046 0 2-0.8954 2-2v-10c0-1.1046-0.89543-2-2-2h-12zm7 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fil#4f4f4f0e0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_joypad.svg b/editor/icons/dark/icon_joypad.svg
deleted file mode 100644
index a6d739c31b..0000000000
--- a/editor/icons/dark/icon_joypad.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 3c-0.55226 5.52e-5 -0.99994 0.44774-1 1v8c5.52e-5 0.55226 0.44774 0.99994 1 1h14c0.55226-5.5e-5 0.99994-0.44774 1-1v-8c-5.5e-5 -0.55226-0.44774-0.99994-1-1h-14zm2 2h2v2h2v2h-2v2h-2v-2h-2v-2h2v-2zm10.5 0a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5 -1.5 1.5 1.5 0 0 1 1.5 -1.5zm-3 3a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5 -1.5 1.5 1.5 0 0 1 1.5 -1.5z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_key.svg b/editor/icons/dark/icon_key.svg
deleted file mode 100644
index a6fb20d1ef..0000000000
--- a/editor/icons/dark/icon_key.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m11 4a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z"/>
-<rect x="1" y="1043.4" width="8" height="2"/>
-<rect x="2" y="1045.4" width="3" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_key_hover.svg b/editor/icons/dark/icon_key_hover.svg
deleted file mode 100644
index c38951eae0..0000000000
--- a/editor/icons/dark/icon_key_hover.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#000000"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_key_invalid.svg b/editor/icons/dark/icon_key_invalid.svg
deleted file mode 100644
index 0ff88aa9ee..0000000000
--- a/editor/icons/dark/icon_key_invalid.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path d="m0.46447 1046.2 2.1213 2.1213-2.1213 2.1213 1.4142 1.4142l2.1213-2.1213 2.1213 2.1213 1.4142-1.4142-2.1213-2.1213 2.1213-2.1213-1.4142-1.4142-2.1213 2.1213-2.1213-2.1213-1.4142 1.4142z" fill="#ff4040"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_key_next.svg b/editor/icons/dark/icon_key_next.svg
deleted file mode 100644
index f3ff31f8f9..0000000000
--- a/editor/icons/dark/icon_key_next.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2h-2z" fill="#00f010"/>
-<path transform="translate(0 1036.4)" d="m11 1a4 4 0 0 0 -3.8691 3h-6.1309v2h1v2h3v-2h2.1328a4 4 0 0 0 2.8672 2.8691v-0.86914h3.6387a4 4 0 0 0 1.3613 -3 4 4 0 0 0 -4 -4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_key_selected.svg b/editor/icons/dark/icon_key_selected.svg
deleted file mode 100644
index 9d16649c67..0000000000
--- a/editor/icons/dark/icon_key_selected.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#5caeff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_key_value.svg b/editor/icons/dark/icon_key_value.svg
deleted file mode 100644
index 7309f498dd..0000000000
--- a/editor/icons/dark/icon_key_value.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_key_xform.svg b/editor/icons/dark/icon_key_xform.svg
deleted file mode 100644
index 6161195b33..0000000000
--- a/editor/icons/dark/icon_key_xform.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#e3383d"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_keyboard.svg b/editor/icons/dark/icon_keyboard.svg
deleted file mode 100644
index c8d0d6d4b9..0000000000
--- a/editor/icons/dark/icon_keyboard.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-1v9a0.99998 0.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1 -1v-9h-1z" fill="#4f4f4f"/>
-<rect x="27" y="1038.4" width="7" height="14" fill="#000000"/>
-<path transform="translate(0 1036.4)" d="m4 2a1 1 0 0 0 -1 1v9.084a1 0.91667 0 0 0 1 0.91602h8a1 0.91667 0 0 0 1 -0.91602v-9.084a1 1 0 0 0 -1 -1h-8zm1 2h2v3l2-3h2l-2 3 2 4h-2l-2-4v4h-2v-7z" fil#4f4f4f0e0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_kinematic_body.svg b/editor/icons/dark/icon_kinematic_body.svg
deleted file mode 100644
index a2c85ab7d0..0000000000
--- a/editor/icons/dark/icon_kinematic_body.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 4v1h1v-1h-1zm1 1v1h-1v1h-1v1h-1v1 2h1v-2h1v1 1h1v-1h5v1h1v-2h1v2h1v-2-1h-1v-1h-1v-1h-1v-1h-1v1h-3v-1h-1zm5 0h1v-1h-1v1zm0 6h-2v1h2v-1zm-5 0v1h2v-1h-2zm0-4h1v1h-1v-1zm4 0h1v1h-1v-1z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_kinematic_body_2d.svg b/editor/icons/dark/icon_kinematic_body_2d.svg
deleted file mode 100644
index c32e0318fa..0000000000
--- a/editor/icons/dark/icon_kinematic_body_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 4v1h1v-1h-1zm1 1v1h-1v1h-1v1h-1v1 2h1v-2h1v1 1h1v-1h5v1h1v-2h1v2h1v-2-1h-1v-1h-1v-1h-1v-1h-1v1h-3v-1h-1zm5 0h1v-1h-1v1zm0 6h-2v1h2v-1zm-5 0v1h2v-1h-2zm0-4h1v1h-1v-1zm4 0h1v1h-1v-1z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_label.svg b/editor/icons/dark/icon_label.svg
deleted file mode 100644
index 0142250c0a..0000000000
--- a/editor/icons/dark/icon_label.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 3a1.0001 1.0001 0 0 0 -0.70703 0.29297l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1.0001 1.0001 0 0 0 0.70703 0.29297h8a1.0001 1.0001 0 0 0 1 -1v-8a1.0001 1.0001 0 0 0 -1 -1h-8zm-1 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" color="#000000" color-rendering="auto" fill="#29d739" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_large_texture.svg b/editor/icons/dark/icon_large_texture.svg
deleted file mode 100644
index 0bb85cbc23..0000000000
--- a/editor/icons/dark/icon_large_texture.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v1 2h1v-2h2v-1h-3zm11 0v1h2v2h1v-3h-3zm-3 5v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-1-1h-1v-1h-1zm-8 6v2 1h3v-1h-2v-2h-1zm13 0v2h-2v1h3v-1-2h-1z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_light_2d.svg b/editor/icons/dark/icon_light_2d.svg
deleted file mode 100644
index 814b2325f4..0000000000
--- a/editor/icons/dark/icon_light_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3 -4.5801 5 5 0 0 0 -5 -5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3 -3 3 3 0 0 1 3 -3zm-1 11v1h2v-1h-2z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_light_occluder_2d.svg b/editor/icons/dark/icon_light_occluder_2d.svg
deleted file mode 100644
index 71099c655b..0000000000
--- a/editor/icons/dark/icon_light_occluder_2d.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff" fill-opacity=".98824">
-<rect x="1" y="1039.4" width="14" height="2"/>
-<rect x="1" y="1042.4" width="14" height="2"/>
-<rect x="1" y="1045.4" width="14" height="2"/>
-<rect x="1" y="1048.4" width="14" height="2"/>
-<rect x="2" y="1037.4" width="1" height="14"/>
-<rect x="13" y="1037.4" width="1" height="14"/>
-<rect x="1" y="1037.4" width="14" height=".99998"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_line_2d.svg b/editor/icons/dark/icon_line_2d.svg
deleted file mode 100644
index 319d6bdea7..0000000000
--- a/editor/icons/dark/icon_line_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1045.4 3 4 3-10 3 6 3-2" fill="none" stroke="#6d90ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_line_edit.svg b/editor/icons/dark/icon_line_edit.svg
deleted file mode 100644
index 0daf666e27..0000000000
--- a/editor/icons/dark/icon_line_edit.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m1 11c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2h-2-10-2z"/>
-<rect x="2" y="1040.4" width="2" height="5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_line_shape_2d.svg b/editor/icons/dark/icon_line_shape_2d.svg
deleted file mode 100644
index f6c036bb2e..0000000000
--- a/editor/icons/dark/icon_line_shape_2d.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" stroke="#68b6ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
-<path d="m1 1037.4 14 14" fill="#68b6ff" fill-rule="evenodd" stroke-opacity=".39216"/>
-<path d="m3 1039.4 10 10" fill="none" stroke-opacity=".58824"/>
-<path d="m5 1041.4 6 6" fill="none"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_link_button.svg b/editor/icons/dark/icon_link_button.svg
deleted file mode 100644
index c8d7e1e5c5..0000000000
--- a/editor/icons/dark/icon_link_button.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m6 7a0.99998 0.99998 0 0 0 -1 1 0.99998 0.99998 0 0 0 1 1h4a0.99998 0.99998 0 0 0 1 -1 0.99998 0.99998 0 0 0 -1 -1h-4z"/>
-<path transform="translate(0 1036.4)" d="m6 3a5 5 0 0 0 -4.3301 2.5 5 5 0 0 0 0 5 5 5 0 0 0 4.3301 2.5h1v-2h-1a3 3 0 0 1 -3 -3 3 3 0 0 1 3 -3h1v-2h-1zm3 0v2h1a3 3 0 0 1 3 3 3 3 0 0 1 -3 3h-1v2h1a5 5 0 0 0 4.3301 -2.5 5 5 0 0 0 0 -5 5 5 0 0 0 -4.3301 -2.5h-1z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_list_select.svg b/editor/icons/dark/icon_list_select.svg
deleted file mode 100644
index c0fe4dd763..0000000000
--- a/editor/icons/dark/icon_list_select.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m1 1v14h8.2578l-0.82227-2h-5.4355v-2h4.6113l-0.82227-2h-3.7891v-2h3.8867a1.5002 1.5002 0 0 1 1.0977 -0.49805v-0.0019531a1.5002 1.5002 0 0 1 0.58594 0.11133l0.94531 0.38867h0.48438v0.19922l2 0.82227v-7.0215h-11zm2 2h7v2h-7v-2zm7.7559 7.7559l0.52344 1.2734a1.5002 1.5002 0 0 1 0.48047 -0.26953 1.5002 1.5002 0 0 1 0.24023 -0.43945v-0.050781l-1.2441-0.51367z" fill-opacity=".99608"/>
-<path d="m16 1047.7-8-3.291 3.291 8 0.9471-2.8201 1.8836 1.8835 0.9418-0.9418-1.8836-1.8835z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_listener.svg b/editor/icons/dark/icon_listener.svg
deleted file mode 100644
index 5450428686..0000000000
--- a/editor/icons/dark/icon_listener.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m13.928 1038.4-1.7383 1.0039a6 6 0 0 1 0.81055 2.9961 6 6 0 0 1 -0.80859 2.998l1.7363 1.002a8 8 0 0 0 0 -8z" fill="#ff5f5f"/>
-<rect x="3" y="1049.4" width="1" height="2" fill="#ff5f5f"/>
-<path transform="translate(0 1036.4)" d="m6 1a5 5 0 0 0 -5 5h2a3 3 0 0 1 3 -3 3 3 0 0 1 3 3h2a5 5 0 0 0 -5 -5z" fill="#ff5f5f"/>
-<path d="m10 1042.4c0 4-3 4-3 5 0 3-2 3-3 3" fill="none" stroke="#ff5f5f" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_load.svg b/editor/icons/dark/icon_load.svg
deleted file mode 100644
index 6cee92ad23..0000000000
--- a/editor/icons/dark/icon_load.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 2c-1.1046 0-2 0.8954-2 2v9c0 1.1046 0.89543 2 2 2h9c1.1046 0 1.8184-0.91043 2-2l1-6c0.003977-0.18354-0.042648-0.3412-0.13477-0.5-0.17849-0.30916-0.50825-0.49972-0.86523-0.5h-8c-0.35698 2.824e-4 -0.68674 0.19084-0.86523 0.5-0.092118 0.1588-0.13874 0.3399-0.13477 0.52344l-1 5.9766c-0.091144 0.54473-0.44772 1-1 1s-1-0.4477-1-1v-9c0-0.5523 0.44772-1 1-1h2c0.55228 0 1 0.4477 1 1a1 1 0 0 0 0.29297 0.70703 1 1 0 0 0 0.70703 0.29297h4 1a1 1 0 0 0 -0.29297 -0.70703 1 1 0 0 0 -0.70703 -0.29297h-4c0-1.1046-0.89543-2-2-2h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_lock.svg b/editor/icons/dark/icon_lock.svg
deleted file mode 100644
index ea400fbec0..0000000000
--- a/editor/icons/dark/icon_lock.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m2 8v7h12v-7h-12zm5 2h2v3h-2v-3z"/>
-<path transform="translate(0 1036.4)" d="m8 1a5 5 0 0 0 -5 5h2a3 3 0 0 1 3 -3 3 3 0 0 1 3 3h2a5 5 0 0 0 -5 -5z"/>
-<rect x="3" y="1042.4" width="2" height="2"/>
-<rect x="11" y="1042.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_loop.svg b/editor/icons/dark/icon_loop.svg
deleted file mode 100644
index 988ce491f6..0000000000
--- a/editor/icons/dark/icon_loop.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1v2h-2a5 5 0 0 0 -5 5 5 5 0 0 0 1.0039 2.9961l1.4355-1.4355a3 3 0 0 1 -0.43945 -1.5605 3 3 0 0 1 3 -3h2v2l2-1.5 2-1.5-2-1.5-2-1.5zm5.9961 4.0039l-1.4355 1.4355a3 3 0 0 1 0.43945 1.5605 3 3 0 0 1 -3 3h-2v-2l-2 1.5-2 1.5 2 1.5 2 1.5v-2h2a5 5 0 0 0 5 -5 5 5 0 0 0 -1.0039 -2.9961z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_loop_interpolation.svg b/editor/icons/dark/icon_loop_interpolation.svg
deleted file mode 100644
index dfda7d39ba..0000000000
--- a/editor/icons/dark/icon_loop_interpolation.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<circle cx="3" cy="1048.4" r="2"/>
-<path transform="translate(0 1036.4)" d="m4 3a2 2 0 0 0 -1.7324 1 2 2 0 0 0 -0.26562 1h-0.0019531v0.046875 6.9531h2v-5-2h2v-2h-2z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m6 1037.4v6l4-3z" fill-rule="evenodd"/>
-<circle cx="13" cy="1040.4" r="2"/>
-<path transform="translate(0 1036.4)" d="m12 4v5 2h-2v2h2a2 2 0 0 0 1.7324 -1 2 2 0 0 0 0.26562 -1h0.001953v-7h-2z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m10 1045.4v6l-4-3z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_main_play.svg b/editor/icons/dark/icon_main_play.svg
deleted file mode 100644
index 531d704dac..0000000000
--- a/editor/icons/dark/icon_main_play.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m4 1048.4v-8l7 4z" fill="#4f4f4f" fill-rule="evenodd" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_margin_container.svg b/editor/icons/dark/icon_margin_container.svg
deleted file mode 100644
index 71fddc2e95..0000000000
--- a/editor/icons/dark/icon_margin_container.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z"/>
-<path d="m4 1042.4v4l2-2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_cube.svg b/editor/icons/dark/icon_material_preview_cube.svg
deleted file mode 100644
index 90ee4fa933..0000000000
--- a/editor/icons/dark/icon_material_preview_cube.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m8 1l-7 3v8l7 3 7-3v-8l-7-3z" fill="#d5d5d5"/>
-<path d="m1 1040.4 7 3 7-3-7-3z" fill="#000000"/>
-<path d="m8 1051.4-7-3v-8l7 3z" fil#4f4f4f0e0"/>
-<path d="m8 1051.4 7-3v-8l-7 3z" fill="#d5d5d5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_cube_off.svg b/editor/icons/dark/icon_material_preview_cube_off.svg
deleted file mode 100644
index 45c013103b..0000000000
--- a/editor/icons/dark/icon_material_preview_cube_off.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m8 1l-7 3v8l7 3 7-3v-8l-7-3z" fill="#d5d5d5"/>
-<path d="m1 1040.4 7 3 7-3-7-3z" fill="#000000"/>
-<path d="m8 1051.4-7-3v-8l7 3z" fil#4f4f4f0e0"/>
-<path d="m8 1051.4 7-3v-8l-7 3z" fill="#d5d5d5"/>
-<path d="m8 1037.4-7 3v8l7 3 7-3v-8l-7-3z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_light_1.svg b/editor/icons/dark/icon_material_preview_light_1.svg
deleted file mode 100644
index 8028b1e798..0000000000
--- a/editor/icons/dark/icon_material_preview_light_1.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v2h2v-2h-2zm-3.2422 1.3438l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm-1 1h2v1 5h-1v-5h-1v-1zm-6 2v2h2v-2h-2zm12 0v2h2v-2h-2zm-9.2422 3.8281l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-5.2422 2.1719v2h2v-2h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_light_1_off.svg b/editor/icons/dark/icon_material_preview_light_1_off.svg
deleted file mode 100644
index 63a2094e67..0000000000
--- a/editor/icons/dark/icon_material_preview_light_1_off.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v2h2v-2h-2zm-3.2422 1.3438l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm-1 1h2v1 5h-1v-5h-1v-1zm-6 2v2h2v-2h-2zm12 0v2h2v-2h-2zm-9.2422 3.8281l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-5.2422 2.1719v2h2v-2h-2z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_light_2.svg b/editor/icons/dark/icon_material_preview_light_2.svg
deleted file mode 100644
index 745f943a17..0000000000
--- a/editor/icons/dark/icon_material_preview_light_2.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v2h2v-2h-2zm-3.2422 1.3438l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm-1 1h2v2 1h-2v1h2v1h-2-1v-2-1h2v-1h-1v-1zm-6 2v2h2v-2h-2zm12 0v2h2v-2h-2zm-9.2422 3.8281l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-5.2422 2.1719v2h2v-2h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_light_2_off.svg b/editor/icons/dark/icon_material_preview_light_2_off.svg
deleted file mode 100644
index 283cad0011..0000000000
--- a/editor/icons/dark/icon_material_preview_light_2_off.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v2h2v-2h-2zm-3.2422 1.3438l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm-1 1h2v2 1h-2v1h2v1h-2-1v-2-1h2v-1h-1v-1zm-6 2v2h2v-2h-2zm12 0v2h2v-2h-2zm-9.2422 3.8281l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-5.2422 2.1719v2h2v-2h-2z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m7 1v2h2v-2h-2zm-3.2422 1.3438l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm-1 1h2v2 1h-2v1h2v1h-2-1v-2-1h2v-1h-1v-1zm-6 2v2h2v-2h-2zm12 0v2h2v-2h-2zm-9.2422 3.8281l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm8.4844 0l-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141-1.4141-1.4141zm-5.2422 2.1719v2h2v-2h-2z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_sphere.svg b/editor/icons/dark/icon_material_preview_sphere.svg
deleted file mode 100644
index a1bf99f984..0000000000
--- a/editor/icons/dark/icon_material_preview_sphere.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_material_preview_sphere_off.svg b/editor/icons/dark/icon_material_preview_sphere_off.svg
deleted file mode 100644
index 57e38534ab..0000000000
--- a/editor/icons/dark/icon_material_preview_sphere_off.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_matrix.svg b/editor/icons/dark/icon_matrix.svg
deleted file mode 100644
index 5e10864279..0000000000
--- a/editor/icons/dark/icon_matrix.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#e3383d">
-<rect x="1" y="1039.4" width="1" height="12"/>
-<rect x="1" y="1039.4" width="3" height="1"/>
-<rect x="1" y="1050.4" width="3" height="1"/>
-<rect x="10" y="1050.4" width="3" height="1"/>
-<rect x="10" y="1039.4" width="3" height="1"/>
-<rect x="12" y="1039.4" width="1" height="12"/>
-<rect x="3" y="1041.4" width="2" height="2"/>
-<rect x="6" y="1041.4" width="2" height="2"/>
-<rect x="9" y="1041.4" width="2" height="2"/>
-<rect x="3" y="1044.4" width="2" height="2"/>
-<rect x="6" y="1044.4" width="2" height="2"/>
-<rect x="9" y="1044.4" width="2" height="2"/>
-<rect x="3" y="1047.4" width="2" height="2"/>
-<rect x="6" y="1047.4" width="2" height="2"/>
-<rect x="9" y="1047.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_menu_button.svg b/editor/icons/dark/icon_menu_button.svg
deleted file mode 100644
index 752e45f761..0000000000
--- a/editor/icons/dark/icon_menu_button.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m1 1v4h14v-4h-14zm5 1h4l-2 2-2-2z"/>
-<path transform="translate(0 1036.4)" d="m2 6a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1 -1v-7a1 1 0 0 0 -1 -1h-12zm1 2h10v2h-10v-2zm0 3h10v2h-10v-2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mesh.svg b/editor/icons/dark/icon_mesh.svg
deleted file mode 100644
index 455d34b0cb..0000000000
--- a/editor/icons/dark/icon_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -1.0312 -1.75h0.03125v-6.5215a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm2.4141 3h5.8574a2 2 0 0 0 0.72852 0.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141l6.5859 6.5859h-5.8574a2 2 0 0 0 -0.72852 -0.73047v-5.8555z" fill="#fea900"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mesh_instance.svg b/editor/icons/dark/icon_mesh_instance.svg
deleted file mode 100644
index 7233e5099e..0000000000
--- a/editor/icons/dark/icon_mesh_instance.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="3" cy="1049.4" r="2" fill="#ff5f5f" fill-opacity=".99608"/>
-<rect x="2" y="1039.4" width="2" height="8.5" fill="#ff5f5f" fill-opacity=".99608"/>
-<circle cx="3" cy="1039.4" r="2" fill="#ff5f5f" fill-opacity=".99608"/>
-<rect transform="rotate(90)" x="1038.4" y="-11.5" width="2" height="8.5" fill="#ff5f5f" fill-opacity=".99608"/>
-<circle cx="13" cy="1039.4" r="2" fill="#ff5f5f" fill-opacity=".99608"/>
-<rect x="12" y="1039.1" width="2" height="8.5" fill="#ff5f5f" fill-opacity=".99608"/>
-<circle cx="13" cy="1049.4" r="2" fill="#ff5f5f" fill-opacity=".99608"/>
-<rect transform="rotate(90)" x="1048.4" y="-12.25" width="2" height="8.5" fill="#ff5f5f" fill-opacity=".99608"/>
-<path d="m3 1039.4 10 10" fill="none" stroke="#ff5f5f" stroke-opacity=".99608" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mesh_library.svg b/editor/icons/dark/icon_mesh_library.svg
deleted file mode 100644
index 4c74ec127a..0000000000
--- a/editor/icons/dark/icon_mesh_library.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.2695v-2h-2.2715a2 2 0 0 0 -0.72852 -0.73047v-5.8555l3 3v-0.41406a2.0002 2.0002 0 0 1 0.80859 -1.6055l-2.3945-2.3945h5.8574a2 2 0 0 0 0.72852 0.73047v1.2695a2.0002 2.0002 0 0 1 0.99805 0.27148 2.0002 2.0002 0 0 1 1.002 -0.27148v-1.2715a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm6 7v1 5 1h5c0.55228 0 1-0.4477 1-1v-5c0-0.5523-0.44772-1-1-1v4l-1-1-1 1v-4h-3z" fill="#fea900"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_aabb.svg b/editor/icons/dark/icon_mini_aabb.svg
deleted file mode 100644
index d9c710ee1c..0000000000
--- a/editor/icons/dark/icon_mini_aabb.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m5 1041.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6h-2zm0 2v2a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#ee7991"/>
-<path d="m3 1046.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6h-2zm0 2v2a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#f39bad"/>
-<path d="m13 1043.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z" fill="#ee7991"/>
-<path d="m13 1049.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z" fill="#ee7991"/>
-<rect transform="matrix(0,1,1,0,0,0)" x="1041.4" y="11" width="8" height="2" fill="#ee7991"/>
-<path d="m8 1044.4v8h2a3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3v-2h-2zm2 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v-2z" fill="#f39bad"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_array.svg b/editor/icons/dark/icon_mini_array.svg
deleted file mode 100644
index 08ab2e77f8..0000000000
--- a/editor/icons/dark/icon_mini_array.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#4f4f4f">
-<rect x="11" y="1047.4" width="2" height="3"/>
-<path d="m14 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<rect x="7" y="1047.4" width="2" height="3"/>
-<path d="m10 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<path d="m4 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m4 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="4" y="-1050.4" width="2" height="6"/>
-<rect x="10" y="1044.4" width="1" height="2"/>
-<rect x="14" y="1044.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_basis.svg b/editor/icons/dark/icon_mini_basis.svg
deleted file mode 100644
index e0dc132d12..0000000000
--- a/editor/icons/dark/icon_mini_basis.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<rect transform="scale(-1,1)" x="-2" y="1044.4" width="2" height="6" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-2" y="1044.4" width="1" height="2" fill="#e3ec69"/>
-<path d="m2 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1z" fill="#e3ec69"/>
-<path d="m2 1050.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1z" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-2" y="1042.4" width="2" height="3.9999" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-9" y="1044.4" width="2" height="2" fill="#e3ec69"/>
-<path d="m7 1048.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<path transform="scale(-1,1)" d="m-7 1050.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-7" y="1048.4" width="2" height="2" fill="#e3ec69"/>
-<rect x="10" y="1046.4" width="2" height="3.9999" fill="#eef39f"/>
-<rect x="10" y="1042.4" width="2" height="2" fill="#eef39f"/>
-<rect transform="scale(-1,1)" x="-16" y="1044.4" width="2" height="2" fill="#e3ec69"/>
-<path d="m14 1048.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<path transform="scale(-1,1)" d="m-14 1050.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-14" y="1048.4" width="2" height="2" fill="#e3ec69"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_boolean.svg b/editor/icons/dark/icon_mini_boolean.svg
deleted file mode 100644
index b8861c9f17..0000000000
--- a/editor/icons/dark/icon_mini_boolean.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#8da6f0">
-<rect transform="scale(-1,1)" x="-2" y="1044.4" width="2" height="6"/>
-<rect transform="scale(-1,1)" x="-2" y="1044.4" width="1" height="2"/>
-<path d="m2 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="13" y="-1047.4" width="2" height="5"/>
-<path d="m2 1050.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z"/>
-<rect transform="scale(-1,1)" x="-2" y="1042.4" width="2" height="3.9999"/>
-<path d="m16 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m7 1044.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z"/>
-<path d="m11 1044.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_color.svg b/editor/icons/dark/icon_mini_color.svg
deleted file mode 100644
index 77526c4a3c..0000000000
--- a/editor/icons/dark/icon_mini_color.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path transform="translate(0 1040.4)" d="m4 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1h1v-2h-1z" fill="#ff2929"/>
-<path transform="translate(0 1040.4)" d="m14 4a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1 -1h1v-2h-1z" fill="#70bfff"/>
-<path transform="translate(0 1040.4)" d="m6 2v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1 -1v-5h-2z" fill="#7aff70"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_color_array.svg b/editor/icons/dark/icon_mini_color_array.svg
deleted file mode 100644
index 12494655ce..0000000000
--- a/editor/icons/dark/icon_mini_color_array.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<rect y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<path transform="translate(0 1040.4)" d="m6 3.5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1h1v-2h-1z" fill="#ff2929"/>
-<rect x="10" y="1046.9" width="2" height="3" fill="#70bfff"/>
-<path d="m13 1043.9a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z" fill="#70bfff"/>
-<path transform="translate(0 1040.4)" d="m7 1.5v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1 -1v-5h-2z" fill="#7aff70"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_dictionary.svg b/editor/icons/dark/icon_mini_dictionary.svg
deleted file mode 100644
index eb68709c4f..0000000000
--- a/editor/icons/dark/icon_mini_dictionary.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#77edb1">
-<rect transform="scale(1,-1)" x="13" y="-1047.4" width="2" height="5"/>
-<rect transform="scale(1,-1)" x="15" y="-1046.4" width="1" height="2"/>
-<path d="m16 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m11 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<path d="m11 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect x="6" y="1046.4" width="2" height="3.9999"/>
-<rect x="6" y="1042.4" width="2" height="2"/>
-<path d="m3 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<path d="m3 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect x="3" y="1042.4" width="2" height="8"/>
-<rect x="11" y="1044.4" width="1" height="2"/>
-<rect x="11" y="1048.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_float.svg b/editor/icons/dark/icon_mini_float.svg
deleted file mode 100644
index 2eb71fd85e..0000000000
--- a/editor/icons/dark/icon_mini_float.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#61daf4">
-<rect y="1045.4" width="2" height="5"/>
-<rect x="2" y="1046.4" width="2" height="2"/>
-<path d="m3 1042.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="6" y="-1047.4" width="2" height="5"/>
-<path d="m9 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect transform="scale(1,-1)" x="12" y="-1047.4" width="2" height="5"/>
-<path d="m15 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect x="9" y="1048.4" width="1" height="2"/>
-<rect x="14" y="1044.4" width="2" height="2"/>
-<rect x="15" y="1048.4" width="1" height="2"/>
-<rect x="3" y="1042.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_float_array.svg b/editor/icons/dark/icon_mini_float_array.svg
deleted file mode 100644
index 7d08903461..0000000000
--- a/editor/icons/dark/icon_mini_float_array.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<rect y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<path d="m6 1042.4a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1 -1v-2z" fill="#61daf4"/>
-<path d="m10 1042.4v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1 -1v-1h1v-2h-1v-2h-2z" fill="#61daf4"/>
-<path d="m7 1042.4v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1 -1v-5h-2z" fill="#c6f2fb"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_image.svg b/editor/icons/dark/icon_mini_image.svg
deleted file mode 100644
index a3f273078c..0000000000
--- a/editor/icons/dark/icon_mini_image.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#93f1b9">
-<rect y="1045.4" width="2" height="3.9999"/>
-<rect x="3" y="1043.4" width="2" height="6"/>
-<path d="m5 1043.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="6" y="1046.4" width="2" height="3"/>
-<rect y="1041.4" width="2" height="2"/>
-<rect x="6" y="1043.4" width="2" height="6"/>
-<path d="m8 1043.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="9" y="1046.4" width="2" height="3"/>
-<path d="m14 1049.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m14 1043.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="14" y="-1049.4" width="2" height="6"/>
-<path d="m13 1052.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z"/>
-<rect x="12" y="1050.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_input.svg b/editor/icons/dark/icon_mini_input.svg
deleted file mode 100644
index c64db97127..0000000000
--- a/editor/icons/dark/icon_mini_input.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#adf18f">
-<path d="m10 1050.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z"/>
-<path d="m10 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect transform="scale(-1)" x="-10" y="-1052.4" width="2" height="8"/>
-<rect y="1046.4" width="2" height="3.9999"/>
-<rect x="3" y="1044.4" width="2" height="6"/>
-<path d="m5 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="6" y="1047.4" width="2" height="3"/>
-<rect y="1042.4" width="2" height="2"/>
-<rect transform="scale(1,-1)" x="13" y="-1047.4" width="2" height="5"/>
-<rect transform="scale(1,-1)" x="15" y="-1046.4" width="1" height="2"/>
-<path d="m16 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_int_array.svg b/editor/icons/dark/icon_mini_int_array.svg
deleted file mode 100644
index 625252bba2..0000000000
--- a/editor/icons/dark/icon_mini_int_array.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path transform="translate(0 1040.4)" d="m0 0v2 8 2h2 2v-2h-2v-8h2v-2h-4zm12 0v2h2v8h-2v2h4v-2-8-2h-2-2z" fill="#4f4f4f"/>
-<path transform="translate(0 1040.4)" d="m3 2v2h2v-2h-2zm0 4v4h2v-4h-2z" fill="#7dc6ef"/>
-<path transform="translate(0 1040.4)" d="m5 4v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3 -3h-2z" fill="#c8e7f9"/>
-<path transform="translate(0 1040.4)" d="m10 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1 -1v-1h1v-2h-1v-2h-2z" fill="#7dc6ef"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_integer.svg b/editor/icons/dark/icon_mini_integer.svg
deleted file mode 100644
index 05d09d9823..0000000000
--- a/editor/icons/dark/icon_mini_integer.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#7dc6ef">
-<rect x="1" y="1046.4" width="2" height="3.9999"/>
-<rect x="4" y="1044.4" width="2" height="6"/>
-<path d="m7 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="8" y="1047.4" width="2" height="3"/>
-<rect x="1" y="1042.4" width="2" height="2"/>
-<rect transform="scale(1,-1)" x="12" y="-1047.4" width="2" height="5"/>
-<rect transform="scale(1,-1)" x="14" y="-1046.4" width="2" height="2"/>
-<path d="m15 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect x="5" y="1044.4" width="2" height="2"/>
-<rect transform="scale(1,-1)" x="15" y="-1050.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_matrix3.svg b/editor/icons/dark/icon_mini_matrix3.svg
deleted file mode 100644
index e0dc132d12..0000000000
--- a/editor/icons/dark/icon_mini_matrix3.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<rect transform="scale(-1,1)" x="-2" y="1044.4" width="2" height="6" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-2" y="1044.4" width="1" height="2" fill="#e3ec69"/>
-<path d="m2 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1z" fill="#e3ec69"/>
-<path d="m2 1050.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1z" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-2" y="1042.4" width="2" height="3.9999" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-9" y="1044.4" width="2" height="2" fill="#e3ec69"/>
-<path d="m7 1048.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<path transform="scale(-1,1)" d="m-7 1050.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-7" y="1048.4" width="2" height="2" fill="#e3ec69"/>
-<rect x="10" y="1046.4" width="2" height="3.9999" fill="#eef39f"/>
-<rect x="10" y="1042.4" width="2" height="2" fill="#eef39f"/>
-<rect transform="scale(-1,1)" x="-16" y="1044.4" width="2" height="2" fill="#e3ec69"/>
-<path d="m14 1048.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<path transform="scale(-1,1)" d="m-14 1050.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#e3ec69"/>
-<rect transform="scale(-1,1)" x="-14" y="1048.4" width="2" height="2" fill="#e3ec69"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_object.svg b/editor/icons/dark/icon_mini_object.svg
deleted file mode 100644
index 8cbbfa2808..0000000000
--- a/editor/icons/dark/icon_mini_object.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#79f3e8">
-<path d="m8 1050.4a3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3v-2h-2v8h2zm0-2v-2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z"/>
-<path d="m3 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m3 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<path d="m15 1044.4v5a3 3 0 0 1 -3 3v-2a1 1 0 0 0 1 -1v-5h2z"/>
-<path d="m3 1050.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z"/>
-<path d="m3 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="11" y="1050.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_path.svg b/editor/icons/dark/icon_mini_path.svg
deleted file mode 100644
index d09f56e753..0000000000
--- a/editor/icons/dark/icon_mini_path.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#6993ec">
-<rect transform="scale(1,-1)" x="6" y="-1047.4" width="2" height="5"/>
-<rect transform="scale(1,-1)" x="8" y="-1046.4" width="2" height="2"/>
-<path d="m9 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect transform="scale(1,-1)" x="11" y="-1050.4" width="2" height="8"/>
-<path d="m13 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="14" y="-1050.4" width="2" height="3"/>
-<path d="m2 1048.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z"/>
-<path d="m2 1042.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect transform="scale(-1)" x="-2" y="-1050.4" width="2" height="8"/>
-<rect transform="scale(1,-1)" x="9" y="-1050.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_plane.svg b/editor/icons/dark/icon_mini_plane.svg
deleted file mode 100644
index 5d2ee937c0..0000000000
--- a/editor/icons/dark/icon_mini_plane.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#f77070">
-<path d="m3 1048.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z"/>
-<path d="m3 1042.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect transform="scale(-1)" x="-3" y="-1050.4" width="2" height="8"/>
-<rect transform="scale(1,-1)" x="7" y="-1047.4" width="2" height="5"/>
-<path d="m10 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect x="11" y="1044.4" width="2" height="6"/>
-<path d="m13 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="14" y="1047.4" width="2" height="3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_quat.svg b/editor/icons/dark/icon_mini_quat.svg
deleted file mode 100644
index 7baaf44089..0000000000
--- a/editor/icons/dark/icon_mini_quat.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m3 1049.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z" fill="#ec69a3"/>
-<path d="m3 1043.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z" fill="#ec69a3"/>
-<rect transform="scale(1,-1)" x="3" y="-1051.4" width="2" height="8" fill="#ec69a3"/>
-<rect transform="scale(1,-1)" x="13" y="-1046.4" width="2" height="5" fill="#ec69a3"/>
-<rect transform="scale(1,-1)" x="15" y="-1045.4" width="1" height="2" fill="#ec69a3"/>
-<path d="m16 1049.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z" fill="#ec69a3"/>
-<path d="m4 1043.4v3a3 3 0 0 0 3 3h2v-6h-2v4a1 1 0 0 1 -1 -1v-3h-2z" fill="#f298c0"/>
-<path transform="translate(0 1040.4)" d="m11 3a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6h-2zm0 2v2a1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#ec69a3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_raw_array.svg b/editor/icons/dark/icon_mini_raw_array.svg
deleted file mode 100644
index 57a225a19b..0000000000
--- a/editor/icons/dark/icon_mini_raw_array.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path transform="translate(0 1040.4)" d="m0 0v2 8 2h4v-2h-2v-8h2v-2h-2-2zm12 0v2h2v8h-2v2h4v-2-8-2h-2-2z" fill="#4f4f4f"/>
-<rect x="2" y="1046.4" width="2" height="3" fill="#69ec9e"/>
-<rect x="5" y="1043.4" width="1" height="2" fill="#69ec9e"/>
-<path d="m5 1043.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z" fill="#69ec9e"/>
-<path d="m6 1049.4v-6h2v4a1 1 0 0 0 1 -1v-3h2v3 1a1 1 0 0 0 1 -1v-3h2v3a3 3 0 0 1 -3 3h-2v-0.1758a3 3 0 0 1 -1 0.1758h-2z" fill="#aaf4c8"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_rect2.svg b/editor/icons/dark/icon_mini_rect2.svg
deleted file mode 100644
index d9e9413185..0000000000
--- a/editor/icons/dark/icon_mini_rect2.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#f191a5">
-<rect y="1047.4" width="2" height="3"/>
-<path d="m3 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="13" y="-1047.4" width="2" height="5"/>
-<rect transform="scale(1,-1)" x="15" y="-1046.4" width="1" height="2"/>
-<path d="m16 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m7 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="7" y="-1050.4" width="1" height="2"/>
-<path d="m7 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect x="12" y="1044.4" width="1" height="2"/>
-<path d="m12 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="12" y="-1050.4" width="1" height="2"/>
-<path d="m12 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m7 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="6" y="1046.4" width="2" height="1"/>
-<rect transform="scale(1,-1)" x="3" y="-1046.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_rid.svg b/editor/icons/dark/icon_mini_rid.svg
deleted file mode 100644
index 3fe12d0819..0000000000
--- a/editor/icons/dark/icon_mini_rid.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#69ec9a">
-<rect x="1" y="1047.4" width="2" height="3"/>
-<rect x="7" y="1042.4" width="2" height="1.9999"/>
-<rect x="7" y="1046.4" width="2" height="4"/>
-<rect x="4" y="1044.4" width="1" height="2"/>
-<path d="m4 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<path d="m13 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<path d="m13 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect x="14" y="1042.4" width="2" height="8"/>
-<rect x="13" y="1044.4" width="1" height="2"/>
-<rect x="13" y="1048.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_string.svg b/editor/icons/dark/icon_mini_string.svg
deleted file mode 100644
index 7212058fe6..0000000000
--- a/editor/icons/dark/icon_mini_string.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#6ba7ec">
-<path d="m5 1042.4a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1v2a3 3 0 0 0 3 -3v-2a1 1 0 0 1 1 -1v-2z"/>
-<rect transform="scale(1,-1)" x="7" y="-1047.4" width="2" height="5"/>
-<rect transform="scale(1,-1)" x="9" y="-1046.4" width="2" height="2"/>
-<path d="m10 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path transform="translate(0 1040.4)" d="m15 4a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1 -1h1v-2h-1z"/>
-<rect y="1048.4" width="1" height="2"/>
-<rect x="5" y="1042.4" width="1" height="2"/>
-<rect transform="scale(1,-1)" x="10" y="-1050.4" width="1" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_string_array.svg b/editor/icons/dark/icon_mini_string_array.svg
deleted file mode 100644
index b64221bd70..0000000000
--- a/editor/icons/dark/icon_mini_string_array.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path transform="translate(0 1040.4)" d="m0 0v2 8 2h2 2v-2h-2v-8h2v-2h-2-2zm12 0v2h2v8h-2v2h4v-2-10h-4z" fill="#4f4f4f"/>
-<path d="m7 1042.4a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1v2a3 3 0 0 0 3 -3v-2a1 1 0 0 1 1 -1v-2z" fill="#6ba7ec"/>
-<path d="m14 1044.4a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1 -1v-2z" fill="#6ba7ec"/>
-<path d="m8 1042.4v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1 -1v-1h1v-2h-1v-2h-2z" fill="#b5d3f6"/>
-<rect x="7" y="1042.4" width="1" height="2" fill="#6ba7ec"/>
-<rect x="2" y="1048.4" width="1" height="2" fill="#6ba7ec"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_transform.svg b/editor/icons/dark/icon_mini_transform.svg
deleted file mode 100644
index 43c4bb4a8f..0000000000
--- a/editor/icons/dark/icon_mini_transform.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m4 1042.4-0.9082 2.1816-1.0918-2.1816h-2l2 4-2 4h2l0.9082-2.1816 1.0918 2.1816h2l-2-4 2-4z" fill="#f6a86e"/>
-<path d="m9 1042.4a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1 -1h1v-2h-1z" fill="#f8bf95"/>
-<path transform="translate(0 1040.4)" d="m10 4v2 2 2h2v-2l1 1 1-1v2h2v-2-2-2h-2l-1 2-1-2h-2z" fill="#f6a86e"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_transform2D.svg b/editor/icons/dark/icon_mini_transform2D.svg
deleted file mode 100644
index 38921ea85a..0000000000
--- a/editor/icons/dark/icon_mini_transform2D.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<rect x="5" y="1048.4" width="5" height="2" fill="#ddf4aa"/>
-<path d="m7 1050.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#ddf4aa"/>
-<path d="m7 1042.4v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 2.5977 -1.5 3 3 0 0 0 0 -3 3 3 0 0 0 -2.5977 -1.5z" fill="#ddf4aa"/>
-<rect y="1042.4" width="6" height="2" fill="#c4ec69"/>
-<rect x="2" y="1043.4" width="2" height="7" fill="#c4ec69"/>
-<path transform="translate(0 1040.4)" d="m10 2v8h2a4 4 0 0 0 3.4648 -2 4 4 0 0 0 0 -4 4 4 0 0 0 -3.4648 -2h-2zm2 2a2 2 0 0 1 1.7324 1 2 2 0 0 1 0 2 2 2 0 0 1 -1.7324 1v-4z" fill="#c4ec69"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_variant.svg b/editor/icons/dark/icon_mini_variant.svg
deleted file mode 100644
index aeb23ed2bc..0000000000
--- a/editor/icons/dark/icon_mini_variant.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="#69ecbd">
-<rect x="3" y="1044.4" width="2" height="6"/>
-<rect x="6" y="1044.4" width="2" height="6"/>
-<rect x="3" y="1044.4" width="1" height="2"/>
-<path d="m3 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z"/>
-<path d="m14 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<rect transform="scale(1,-1)" x="14" y="-1052.4" width="2" height="8"/>
-<rect transform="scale(1,-1)" x="11" y="-1047.4" width="2" height="3"/>
-<path d="m3 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z"/>
-<path d="m8 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1v-2z"/>
-<rect x="9" y="1047.4" width="2" height="3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_vector2.svg b/editor/icons/dark/icon_mini_vector2.svg
deleted file mode 100644
index 7abc73c41f..0000000000
--- a/editor/icons/dark/icon_mini_vector2.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m3 1050.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z" fill="#bd91f1"/>
-<rect x="4" y="1044.4" width="2" height="3" fill="#bd91f1"/>
-<rect x="11" y="1048.4" width="5" height="2" fill="#dcc5f8"/>
-<rect x="1" y="1044.4" width="2" height="6" fill="#bd91f1"/>
-<rect x="9" y="1044.4" width="1" height="2" fill="#bd91f1"/>
-<path d="m9 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z" fill="#bd91f1"/>
-<rect transform="scale(1,-1)" x="9" y="-1050.4" width="1" height="2" fill="#bd91f1"/>
-<path d="m9 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z" fill="#bd91f1"/>
-<path d="m13 1050.4a2 2 0 0 1 -1.7321 -1 2 2 0 0 1 0 -2 2 2 0 0 1 1.7321 -1" fill="#dcc5f8"/>
-<path d="m13 1042.4v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 2.5977 -1.5 3 3 0 0 0 0 -3 3 3 0 0 0 -2.5977 -1.5z" fill="#dcc5f8"/>
-<rect x="12" y="1042.4" width="1" height="2" fill="#dcc5f8"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_vector2_array.svg b/editor/icons/dark/icon_mini_vector2_array.svg
deleted file mode 100644
index 18af4c551d..0000000000
--- a/editor/icons/dark/icon_mini_vector2_array.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<rect y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<path transform="translate(0 1040.4)" d="m3 3v6h2a3 3 0 0 0 3 -3v-3h-2v3a1 1 0 0 1 -1 1v-4h-2z" fill="#bd91f1"/>
-<path d="m9 1042.4v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -0.26562 1h-0.00195v0.047 1.9531h2 3v-2h-3a3 3 0 0 0 2.5977 -1.5 3 3 0 0 0 0 -3 3 3 0 0 0 -2.5977 -1.5001h-1z" fill="#dcc5f8"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_vector3.svg b/editor/icons/dark/icon_mini_vector3.svg
deleted file mode 100644
index 88b6f1f53c..0000000000
--- a/editor/icons/dark/icon_mini_vector3.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m3.0004 1050.4a3 3 0 0 0 3 -3h-2a1 1 0 0 1 -1 1v2z" fill="#e286f0"/>
-<rect x="4.0004" y="1044.4" width="2" height="3" fill="#e286f0"/>
-<rect x="1.0004" y="1044.4" width="2" height="6" fill="#e286f0"/>
-<rect x="9.0004" y="1044.4" width="1" height="2" fill="#e286f0"/>
-<path d="m9.0004 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1v-2z" fill="#e286f0"/>
-<rect transform="scale(1,-1)" x="9.0004" y="-1050.4" width="1" height="2" fill="#e286f0"/>
-<path d="m9.0004 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1v2z" fill="#e286f0"/>
-<path transform="translate(0 1040.4)" d="m13 2v1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 2.5977 -1.5 3 3 0 0 0 0 -3 3 3 0 0 0 -0.36328 -0.5h-2.2344z" fill="#eeb9f6"/>
-<rect x="12" y="1042.4" width="3.9996" height="2" fill="#eeb9f6"/>
-<path d="m13 1045.4v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 2.5977 -1.5 3 3 0 0 0 0 -3 3 3 0 0 0 -2.5977 -1.5z" fill="#eeb9f6"/>
-<rect x="12" y="1049.4" width="1" height="2" fill="#eeb9f6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mini_vector3_array.svg b/editor/icons/dark/icon_mini_vector3_array.svg
deleted file mode 100644
index ffa2be67ec..0000000000
--- a/editor/icons/dark/icon_mini_vector3_array.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<rect y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1050.4" width="4" height="2" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="2" height="12" fill="#4f4f4f"/>
-<rect transform="scale(-1,1)" x="-16" y="1040.4" width="4" height="2" fill="#4f4f4f"/>
-<path transform="translate(0 1040.4)" d="m3 3v6h2a3 3 0 0 0 3 -3v-3h-2v3a1 1 0 0 1 -1 1v-4h-2z" fill="#e286f0"/>
-<path transform="translate(0 1040.4)" d="m8 1v2h1 1a1 1 0 0 1 -1 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 2.5977 -1.5 3 3 0 0 0 0 -3 3 3 0 0 0 -0.36523 -0.50195 3 3 0 0 0 0.36523 -0.49805 3 3 0 0 0 0.39844 -1.5h0.003906v-2h-0.76562-2.2344-1z" fill="#eeb9f6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mirror_x.svg b/editor/icons/dark/icon_mirror_x.svg
deleted file mode 100644
index 3e80728396..0000000000
--- a/editor/icons/dark/icon_mirror_x.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#4f4f4f" stroke-opacity=".99608" stroke-width="2">
-<path d="m4 1042.4-2 2 2 2" stroke-linecap="round" stroke-linejoin="round"/>
-<path d="m2 1044.4h11"/>
-<path d="m12 1042.4 2 2-2 2" stroke-linecap="round" stroke-linejoin="round"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mirror_y.svg b/editor/icons/dark/icon_mirror_y.svg
deleted file mode 100644
index 3070219228..0000000000
--- a/editor/icons/dark/icon_mirror_y.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m11.012 1048.4a1.0001 1.0001 0 0 0 -1.7168 -0.6973l-0.29297 0.293v-7.1719l0.29297 0.293a1.0001 1.0001 0 0 0 1.7148 -0.7266 1.0001 1.0001 0 0 0 -0.30078 -0.6875l-2-2a1.0001 1.0001 0 0 0 -1.4141 0l-2 2a1.0001 1.0001 0 1 0 1.4141 1.4141l0.29297-0.293v7.1719l-0.29297-0.293a1.0001 1.0001 0 1 0 -1.4141 1.4141l2 2a1.0001 1.0001 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 0.30273 -0.7168z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_mouse.svg b/editor/icons/dark/icon_mouse.svg
deleted file mode 100644
index f7490f337e..0000000000
--- a/editor/icons/dark/icon_mouse.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1.1016a5 5 0 0 0 -4 4.8984h4v-4.8984zm2 0.0039063v4.8945h4a5 5 0 0 0 -4 -4.8945zm-6 6.8945v2a5 5 0 0 0 5 5 5 5 0 0 0 5 -5v-2h-10z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_move_down.svg b/editor/icons/dark/icon_move_down.svg
deleted file mode 100644
index 437ae2146f..0000000000
--- a/editor/icons/dark/icon_move_down.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-opacity=".99608" stroke-width="2">
-<path d="m4 1045.3 4 5 4-5" stroke-linejoin="round"/>
-<path d="m8 1038.3v11"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_move_point.svg b/editor/icons/dark/icon_move_point.svg
deleted file mode 100644
index 23ffbdfe8d..0000000000
--- a/editor/icons/dark/icon_move_point.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 1.2129 -0.10742l-2.5996-6.3203a1.5002 1.5002 0 0 1 1.3711 -2.0703v-0.0019531a1.5002 1.5002 0 0 1 0.58594 0.11133l6.3184 2.5996a7 7 0 0 0 0.11133 -1.2109 7 7 0 0 0 -7 -7zm2.7559 9.7559l0.52344 1.2734a1.5002 1.5002 0 0 1 0.48047 -0.26953 1.5002 1.5002 0 0 1 0.26953 -0.47852l-1.2734-0.52539z" fill="#000000"/>
-<path transform="translate(0 1036.4)" d="m8 3a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 0.42578 -0.021484l-1.8125-4.4063a1.5002 1.5002 0 0 1 1.3711 -2.0703v-0.0019531a1.5002 1.5002 0 0 1 0.58594 0.11133l4.4082 1.8125a5 5 0 0 0 0.021484 -0.42383 5 5 0 0 0 -5 -5zm2.7559 7.7559l0.44336 1.0801a5 5 0 0 0 0.63867 -0.63281l-1.082-0.44727z" fil#ff4040484"/>
-<path d="m16 1047.7-8-3.291 3.291 8 0.9471-2.8201 1.8836 1.8835 0.9418-0.9418-1.8836-1.8835z" fil#4f4f4f0e0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_move_up.svg b/editor/icons/dark/icon_move_up.svg
deleted file mode 100644
index cf948b75a4..0000000000
--- a/editor/icons/dark/icon_move_up.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-opacity=".99608" stroke-width="2">
-<path d="m4 1043.4 4-5 4 5" stroke-linejoin="round"/>
-<path d="m8 1050.4v-11"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_multi_edit.svg b/editor/icons/dark/icon_multi_edit.svg
deleted file mode 100644
index a22bf3b8cf..0000000000
--- a/editor/icons/dark/icon_multi_edit.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m1.7071 1047.8-0.70711 3.5356l3.5355-0.7071 7.7782-7.7782-2.8284-2.8284zm9.1924-9.1924 2.8284 2.8285 1.4142-1.4142-2.8284-2.8285z"/>
-<rect x="1" y="1037.4" width="2" height="2"/>
-<rect x="1" y="1041.4" width="2" height="2"/>
-<rect x="5" y="1037.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_multi_line.svg b/editor/icons/dark/icon_multi_line.svg
deleted file mode 100644
index 0dda39baad..0000000000
--- a/editor/icons/dark/icon_multi_line.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="10" y="1037.4" width="5" height="1.9999"/>
-<rect transform="rotate(90)" x="1037.4" y="-8" width="2" height="7"/>
-<rect x="1" y="1041.4" width="11" height="1.9999"/>
-<rect x="1" y="1045.4" width="4" height="1.9999"/>
-<rect x="7" y="1045.4" width="8" height="1.9999"/>
-<rect x="1" y="1049.4" width="13" height="1.9999"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_multi_mesh.svg b/editor/icons/dark/icon_multi_mesh.svg
deleted file mode 100644
index 50504f9924..0000000000
--- a/editor/icons/dark/icon_multi_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h1.2695v-1-1h-1.2715a2 2 0 0 0 -0.72852 -0.73047v-5.8555l3.5859 3.5859h1.4141v-1-0.41406l-3.5859-3.5859h5.8574a2 2 0 0 0 0.72852 0.72656v1.2734h2v-1.2695a2 2 0 0 0 1 -1.7305 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm8 7v1.5859 1.4141h-1.4141-1.5859v1 1h3v1 2h2v-1-2h2 1v-2h-2-1v-3h-1-1z" fill="#fea900"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_multi_mesh_instance.svg b/editor/icons/dark/icon_multi_mesh_instance.svg
deleted file mode 100644
index 563ec70f32..0000000000
--- a/editor/icons/dark/icon_multi_mesh_instance.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h1.2695v-1-1h-1.2715a2 2 0 0 0 -0.72852 -0.73047v-5.8555l3.5859 3.5859h1.4141v-1-0.41406l-3.5859-3.5859h5.8574a2 2 0 0 0 0.72852 0.72656v1.2734h2v-1.2695a2 2 0 0 0 1 -1.7305 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 7v2.5859l-1-1v1.4141h-1.4141l1 1h-2.5859v1h1 2v1h0.27148a2 2 0 0 0 1.7285 1v-2h2a2 2 0 0 0 -1.0312 -1.75h0.03125v-0.25h-1v-3h-1z"/>
-<path d="m11 1044.4v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_multi_script.svg b/editor/icons/dark/icon_multi_script.svg
deleted file mode 100644
index a9b577de86..0000000000
--- a/editor/icons/dark/icon_multi_script.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m7 1l-0.56445 2.2578a5 5 0 0 0 -0.68945 0.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -0.28516 0.68555l-2.2539 0.5625v2l2.2578 0.56445a5 5 0 0 0 0.2793 0.6875l-1.1934 1.9902 1.4141 1.4141 1.2422-0.74414v-4.9121h1a2 2 0 0 1 2 -2v-1h4.9121l0.74414-1.2422-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -0.68555 -0.28516l-0.5625-2.2539h-2z"/>
-<path d="m10 1043.4v3h-3v2h3v3h2v-3h3v-2h-3v-3z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_native_script.svg b/editor/icons/dark/icon_native_script.svg
deleted file mode 100644
index 3b88105c24..0000000000
--- a/editor/icons/dark/icon_native_script.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1l-0.56445 2.2578a5 5 0 0 0 -0.68945 0.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -0.28516 0.68555l-2.2539 0.5625h3v1 1h2v-0.95117a2 2 0 0 1 0 -0.048828 2 2 0 0 1 2 -2 2 2 0 0 1 2 2v1h5v-2l-2.2578-0.56445a5 5 0 0 0 -0.2793 -0.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -0.68555 -0.28516l-0.5625-2.2539h-2zm-6 7v4 4h2a3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3v-2h-2zm6 0v2h2v-2h-2zm3 2v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3 -3h-2zm-7 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v-2zm4 0v4h2v-4h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_navigation.svg b/editor/icons/dark/icon_navigation.svg
deleted file mode 100644
index 21f2d5e73c..0000000000
--- a/editor/icons/dark/icon_navigation.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m3 1050.4 5-2 5 2-5-12-5 12z" fill="#ff5f5f" fill-opacity=".99608" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_navigation_2d.svg b/editor/icons/dark/icon_navigation_2d.svg
deleted file mode 100644
index 0f945f3402..0000000000
--- a/editor/icons/dark/icon_navigation_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m3 1050.4 5-2 5 2-5-12-5 12z" fill="#6d90ff" fill-opacity=".98824" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_navigation_mesh.svg b/editor/icons/dark/icon_navigation_mesh.svg
deleted file mode 100644
index 84fa175033..0000000000
--- a/editor/icons/dark/icon_navigation_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 6l-3 8 3-2 3 2-3-8z" fill="#fea900"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_navigation_mesh_instance.svg b/editor/icons/dark/icon_navigation_mesh_instance.svg
deleted file mode 100644
index 295bef078f..0000000000
--- a/editor/icons/dark/icon_navigation_mesh_instance.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1z"/>
-<path d="m15 1051.4-3-8-3 8 3-2z" fill-rule="evenodd"/>
-<rect x="12" y="1040.4" width="2" height="1"/>
-<rect x="12" y="1040.4" width="2" height="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_navigation_polygon.svg b/editor/icons/dark/icon_navigation_polygon.svg
deleted file mode 100644
index e3c5183d7b..0000000000
--- a/editor/icons/dark/icon_navigation_polygon.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g fill="#4f4f4f" fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4.9023a2.1002 2.1002 0 0 1 0.13086 -0.73633l0.47461-1.2637h-4.5078v-10h8.5859l-4.293 4.293a1.0001 1.0001 0 0 0 0 1.4141l1.3262 1.3262 1.4141-3.7695a2.1002 2.1002 0 0 1 1.9922 -1.3613 2.1002 2.1002 0 0 1 0.43555 0.050781l2.2461-2.2461a1.0001 1.0001 0 0 0 -0.70703 -1.707h-12z" color="#000000" color-rendering="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m15 1051.4-3-8-3 8 3-2z"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_navigation_polygon_instance.svg b/editor/icons/dark/icon_navigation_polygon_instance.svg
deleted file mode 100644
index 955fb00c62..0000000000
--- a/editor/icons/dark/icon_navigation_polygon_instance.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff" fill-opacity=".98824" fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4.9023a2.1002 2.1002 0 0 1 0.13086 -0.73633l0.47461-1.2637h-4.5078v-10h8.5859l-4.293 4.293a1.0001 1.0001 0 0 0 0 1.4141l1.3262 1.3262 1.4141-3.7695a2.1002 2.1002 0 0 1 1.9922 -1.3613 2.1002 2.1002 0 0 1 0.43555 0.050781l2.2461-2.2461a1.0001 1.0001 0 0 0 -0.70703 -1.707h-12z" color="#000000" color-rendering="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m15 1051.4-3-8-3 8 3-2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_new.svg b/editor/icons/dark/icon_new.svg
deleted file mode 100644
index 0c8652f1f7..0000000000
--- a/editor/icons/dark/icon_new.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="translate(0 -1.6949e-5)">
-<path transform="translate(0 1036.4)" d="m2 1v14h8v-1h-2v-4h2v-2h4v-2h-5v-5zm8 0v4h4z" fill="#4f4f4f"/>
-<path d="m11 1045.4v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#00f010"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_nine_patch_rect.svg b/editor/icons/dark/icon_nine_patch_rect.svg
deleted file mode 100644
index 0e4a063196..0000000000
--- a/editor/icons/dark/icon_nine_patch_rect.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<rect x="1" y="1037.4" width="2" height="14"/>
-<rect x="1" y="1049.4" width="14" height="2"/>
-<rect x="1" y="1037.4" width="14" height="2"/>
-<rect x="13" y="1037.4" width="2" height="14"/>
-<rect x="1" y="1041.4" width="14" height=".99998"/>
-<rect x="1" y="1046.4" width="14" height=".99998"/>
-<rect transform="rotate(90)" x="1037.4" y="-6" width="14" height=".99998"/>
-<rect transform="rotate(90)" x="1037.4" y="-11" width="14" height=".99998"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_node.svg b/editor/icons/dark/icon_node.svg
deleted file mode 100644
index c5e246e01a..0000000000
--- a/editor/icons/dark/icon_node.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_node_2d.svg b/editor/icons/dark/icon_node_2d.svg
deleted file mode 100644
index 55bc880d18..0000000000
--- a/editor/icons/dark/icon_node_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_node_warning.svg b/editor/icons/dark/icon_node_warning.svg
deleted file mode 100644
index 981af7e3ba..0000000000
--- a/editor/icons/dark/icon_node_warning.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="translate(0 -1.6949e-5)">
-<path transform="translate(0 1036.4)" d="m8.0293 2.002a1.0001 1.0001 0 0 0 -0.88672 0.48438l-6 10a1.0001 1.0001 0 0 0 0.85742 1.5137h12a1.0001 1.0001 0 0 0 0.85742 -1.5137l-6-10a1.0001 1.0001 0 0 0 -0.82812 -0.48438zm-1.0293 2.998h2v5h-2v-5zm0 6h2v2h-2v-2z" color="#000000" color-rendering="auto" fill="#fea900" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_non_favorite.svg b/editor/icons/dark/icon_non_favorite.svg
deleted file mode 100644
index 07090d3e1c..0000000000
--- a/editor/icons/dark/icon_non_favorite.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1.7246l-2.375 4.0977-4.625 1.0977 3.2363 3.4063-0.35938 4.6738 4.1387-1.9766 4.1582 1.9414-0.39648-4.6523 3.2227-3.3926-4.625-1.0977-2.375-4.0977zm0 2.2754l1.6582 2.7773 3.2324 0.74414-2.25 2.3008 0.27539 3.1543-2.9043-1.3164-2.8926 1.3398 0.25195-3.168-2.2617-2.3105 3.2324-0.74414 1.6582-2.7773z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_object.svg b/editor/icons/dark/icon_object.svg
deleted file mode 100644
index e52f4b7513..0000000000
--- a/editor/icons/dark/icon_object.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-rule="evenodd">
-<path d="m8 1043.9v6l6-3v-6z"/>
-<path transform="translate(0 1036.4)" d="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-6 3a1.0001 1.0001 0 0 0 -0.55273 0.89453v6a1.0001 1.0001 0 0 0 0.55273 0.89453l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.89453v-6a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-6-3a1.0001 1.0001 0 0 0 -0.48438 -0.10352zm0.037109 2.1172l3.7637 1.8809-3.7637 1.8828-3.7637-1.8828 3.7637-1.8809zm-5 3.498l4 2v3.7656l-4-2v-3.7656zm10 0v3.7656l-4 2v-3.7656l4-2z" color="#000000" color-rendering="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_occluder_polygon_2d.svg b/editor/icons/dark/icon_occluder_polygon_2d.svg
deleted file mode 100644
index dce4d0e3cd..0000000000
--- a/editor/icons/dark/icon_occluder_polygon_2d.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-rule="evenodd">
-<path d="m1 1045.4 6 6h8v-8l-6-6h-8z" fill="#3552b1"/>
-<path d="m1 1037.4h8l-3 4 3 4h-8z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_omni_light.svg b/editor/icons/dark/icon_omni_light.svg
deleted file mode 100644
index 56d9191cce..0000000000
--- a/editor/icons/dark/icon_omni_light.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3 -4.5801 5 5 0 0 0 -5 -5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3 -3 3 3 0 0 1 3 -3zm-1 11v1h2v-1h-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_option_button.svg b/editor/icons/dark/icon_option_button.svg
deleted file mode 100644
index 5e9114af48..0000000000
--- a/editor/icons/dark/icon_option_button.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 3c-1.1046 0-2 0.89543-2 2v6c0 1.1046 0.89543 2 2 2h5 1 1 2 1c1.1046 0 2-0.89543 2-2v-6c0-1.1046-0.89543-2-2-2h-1-2-1-1-5zm8 2.9863a1.0001 1.0001 0 0 1 0.7168 1.7207l-3 3a1.0001 1.0001 0 0 1 -1.4141 0l-3-3a1.0001 1.0001 0 0 1 0.69727 -1.7168 1.0001 1.0001 0 0 1 0.7168 0.30273l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 0.69727 -0.30664z" fill="#29d739"/>
-<rect x="4" y="1042.4" width="4" height="4" fill="none"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_override.svg b/editor/icons/dark/icon_override.svg
deleted file mode 100644
index 34a1aabccd..0000000000
--- a/editor/icons/dark/icon_override.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 1c-1.108 0-2 0.89199-2 2v1h4v-1h2v1h4v-1c0-1.108-0.89199-2-2-2h-6z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m3 6c-1.108 0-2 0.89199-2 2v5c0 1.108 0.89199 2 2 2h10c1.108 0 2-0.89199 2-2v-5c0-1.108-0.89199-2-2-2h-4v3h2l-3 4-3-4h2v-3h-4z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_packed_data_container.svg b/editor/icons/dark/icon_packed_data_container.svg
deleted file mode 100644
index 6f306165e5..0000000000
--- a/editor/icons/dark/icon_packed_data_container.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1038.4v12h12v-12z" fill="none" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-<rect x="4" y="1040.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="4" y="1043.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="4" y="1046.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="7" y="1040.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="7" y="1043.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="7" y="1046.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="10" y="1040.4" width="2" height="2" fill="#4f4f4f"/>
-<rect x="10" y="1043.4" width="2" height="2" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_packed_scene.svg b/editor/icons/dark/icon_packed_scene.svg
deleted file mode 100644
index 08efa2b833..0000000000
--- a/editor/icons/dark/icon_packed_scene.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m1 7v6h2v2h12v-8h-14z"/>
-<path d="m0.71129 1040.4 0.28871 1.9791l2.2438-0.3273-0.81826-1.9018-1.7143 0.25zm3.6933-0.5387 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5775 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5774 0.81826 1.9018 1.7143-0.25-0.28871-1.9791-2.2438 0.3273z"/>
-<circle cx="3" cy="1049.4" r="2"/>
-<circle cx="13" cy="1049.4" r="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panel.svg b/editor/icons/dark/icon_panel.svg
deleted file mode 100644
index c86f6a129d..0000000000
--- a/editor/icons/dark/icon_panel.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panel_container.svg b/editor/icons/dark/icon_panel_container.svg
deleted file mode 100644
index 14dd0a8bd8..0000000000
--- a/editor/icons/dark/icon_panel_container.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panels_1.svg b/editor/icons/dark/icon_panels_1.svg
deleted file mode 100644
index bfad85ecb9..0000000000
--- a/editor/icons/dark/icon_panels_1.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect y="1036.4" width="16" height="16" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panels_2.svg b/editor/icons/dark/icon_panels_2.svg
deleted file mode 100644
index 9ae6c02c96..0000000000
--- a/editor/icons/dark/icon_panels_2.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect y="1036.4" width="16" height="7"/>
-<rect y="1045.4" width="16" height="7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panels_2_alt.svg b/editor/icons/dark/icon_panels_2_alt.svg
deleted file mode 100644
index 9d5a02d2a3..0000000000
--- a/editor/icons/dark/icon_panels_2_alt.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="9" y="1036.4" width="7" height="16"/>
-<rect y="1036.4" width="7" height="16"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panels_3.svg b/editor/icons/dark/icon_panels_3.svg
deleted file mode 100644
index dddf33f324..0000000000
--- a/editor/icons/dark/icon_panels_3.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect y="1036.4" width="16" height="7"/>
-<rect x="9" y="1045.4" width="7" height="7"/>
-<rect y="1045.4" width="7" height="7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panels_3_alt.svg b/editor/icons/dark/icon_panels_3_alt.svg
deleted file mode 100644
index 9885f5de09..0000000000
--- a/editor/icons/dark/icon_panels_3_alt.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect y="1045.4" width="7" height="7"/>
-<rect x="9" y="1036.4" width="7" height="16"/>
-<rect y="1036.4" width="7" height="7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panels_4.svg b/editor/icons/dark/icon_panels_4.svg
deleted file mode 100644
index 28090e61d7..0000000000
--- a/editor/icons/dark/icon_panels_4.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="9" y="1045.4" width="7" height="7"/>
-<rect y="1045.4" width="7" height="7"/>
-<rect x="9" y="1036.4" width="7" height="7"/>
-<rect y="1036.4" width="7" height="7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_panorama_sky.svg b/editor/icons/dark/icon_panorama_sky.svg
deleted file mode 100644
index f3da955dbd..0000000000
--- a/editor/icons/dark/icon_panorama_sky.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="1038.4" y2="1050.4" gradientTransform="matrix(1.0096 0 0 1.0227 -.0096153 -22.593)" gradientUnits="userSpaceOnUse">
-<stop stop-color="#1ec3ff" offset="0"/>
-<stop stop-color="#b2e1ff" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1037.4)">
-<path d="m1 1039.4c4.2749 2.6091 10.765 2.7449 14 0v12c-3.5849-2.6849-9.7929-2.6544-14 0z" fill="url(#a)" stroke-width="15.242"/>
-<rect x="2" y="1046.4" width="3" height="2" ry="1" fill="#fff"/>
-<rect x="8" y="1044.4" width="4" height="2" ry="1" fill="#fff"/>
-<rect x="10" y="1043.4" width="4" height="2" ry="1" fill="#fff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_parallax_background.svg b/editor/icons/dark/icon_parallax_background.svg
deleted file mode 100644
index fa2ebc1ce7..0000000000
--- a/editor/icons/dark/icon_parallax_background.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<ellipse cx="3" cy="1039.4" r="2" fill="#6e6e6e"/>
-<path d="m1 1039.4a1 1 0 0 1 1 -1v1z" fill="#4f4f4f" fill-opacity=".99608"/>
-<path transform="scale(-1,1)" d="m-15 1039.4a1 1 0 0 1 1 -1v1z" fill="#4f4f4f" fill-opacity=".99608"/>
-<rect x="2" y="1038.4" width="12" height="1" fill="#4f4f4f" fill-opacity=".99608"/>
-<rect x="2" y="1049.4" width="12" height="1" fill="#4f4f4f" fill-opacity=".99608"/>
-<path transform="scale(1,-1)" d="m1-1049.4a1 1 0 0 1 1 -1v1z" fill="#4f4f4f" fill-opacity=".99608"/>
-<path transform="scale(-1)" d="m-15-1049.4a1 1 0 0 1 1 -1v1z" fill="#4f4f4f" fill-opacity=".99608"/>
-<rect x="1" y="1039.4" width="1" height="10" fill="#4f4f4f" fill-opacity=".99608"/>
-<rect x="14" y="1039.4" width="1" height="10" fill="#4f4f4f" fill-opacity=".99608"/>
-<path d="m7 1041.4-3 3 3 3z" fill="#4f4f4f" fill-opacity=".99608" fill-rule="evenodd"/>
-<path d="m9 1041.4 3 3-3 3z" fill="#4f4f4f" fill-opacity=".99608" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_parallax_layer.svg b/editor/icons/dark/icon_parallax_layer.svg
deleted file mode 100644
index 038eac75c2..0000000000
--- a/editor/icons/dark/icon_parallax_layer.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<ellipse cx="3" cy="1039.4" r="2" fill="#6e6e6e"/>
-<path d="m7 1041.4-3 3 3 3z" fill="#6d90ff" fill-opacity=".98824" fill-rule="evenodd"/>
-<path d="m9 1041.4 3 3-3 3z" fill="#6d90ff" fill-opacity=".98824" fill-rule="evenodd"/>
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v10c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-10c9.6e-6 -0.55228 0.44772-0.99999 1-1z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_particle_attractor_2d.svg b/editor/icons/dark/icon_particle_attractor_2d.svg
deleted file mode 100644
index 48e1979f13..0000000000
--- a/editor/icons/dark/icon_particle_attractor_2d.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff" fill-opacity=".98824">
-<path transform="translate(0 1036.4)" d="m8 1a3 7 0 0 0 -3 7 3 7 0 0 0 3 7 3 7 0 0 0 3 -7 3 7 0 0 0 -3 -7zm0 1a2 6 0 0 1 2 6 2 6 0 0 1 -2 6 2 6 0 0 1 -2 -6 2 6 0 0 1 2 -6z"/>
-<path d="m1 1044.4a7 3 0 0 0 7 3 7 3 0 0 0 7 -3 7 3 0 0 0 -7 -3 7 3 0 0 0 -7 3zm1 0a6 2 0 0 1 6 -2 6 2 0 0 1 6 2 6 2 0 0 1 -6 2 6 2 0 0 1 -6 -2z"/>
-<path d="m3.0503 1049.3a3 7 45 0 0 7.0711 -2.8284 3 7 45 0 0 2.8284 -7.071 3 7 45 0 0 -7.0711 2.8284 3 7 45 0 0 -2.8284 7.071zm0.70711-0.7071a2 6 45 0 1 2.8284 -5.6568 2 6 45 0 1 5.6569 -2.8284 2 6 45 0 1 -2.8284 5.6568 2 6 45 0 1 -5.6569 2.8284z"/>
-<path d="m12.95 1049.3a7 3 45 0 0 -2.8284 -7.071 7 3 45 0 0 -7.071 -2.8284 7 3 45 0 0 2.8284 7.071 7 3 45 0 0 7.071 2.8284zm-0.7071-0.7071a6 2 45 0 1 -5.6568 -2.8284 6 2 45 0 1 -2.8284 -5.6568 6 2 45 0 1 5.6568 2.8284 6 2 45 0 1 2.8284 5.6568z"/>
-<circle cx="8" cy="1044.4" r="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_particles.svg b/editor/icons/dark/icon_particles.svg
deleted file mode 100644
index b5d0558eae..0000000000
--- a/editor/icons/dark/icon_particles.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<circle cx="4" cy="1044.4" r="3"/>
-<ellipse cx="8" cy="1042.4" rx="4.5" ry="5"/>
-<path d="m4 1047.4h8v-4h-8z" fill-rule="evenodd"/>
-<circle cx="12" cy="1044.4" r="3"/>
-<circle cx="4" cy="1049.4" r="1"/>
-<circle cx="12" cy="1049.4" r="1"/>
-<circle cx="8" cy="1050.4" r="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_particles_2d.svg b/editor/icons/dark/icon_particles_2d.svg
deleted file mode 100644
index 6ac8c29d15..0000000000
--- a/editor/icons/dark/icon_particles_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3 -3 3 3 0 0 0 -2.5898 -2.9668 4.5 5 0 0 0 -4.4102 -4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_particles_material.svg b/editor/icons/dark/icon_particles_material.svg
deleted file mode 100644
index 5aabbb0252..0000000000
--- a/editor/icons/dark/icon_particles_material.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a4.5 5 0 0 0 -3.5938 2h7.1816a4.5 5 0 0 0 -3.5879 -2z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m4.4062 3a4.5 5 0 0 0 -0.81445 2h8.8105a4.5 5 0 0 0 -0.81445 -2h-7.1816z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m3.5918 5a4.5 5 0 0 0 -0.0058594 0.03125 3 3 0 0 0 -2.4121 1.9688h13.65a3 3 0 0 0 -2.4141 -1.9668 4.5 5 0 0 0 -0.007812 -0.033203h-8.8105z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1.1738 7a3 3 0 0 0 -0.17383 1 3 3 0 0 0 0.17578 1h13.65a3 3 0 0 0 0.17383 -1 3 3 0 0 0 -0.17578 -1h-13.65z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1.1758 9a3 3 0 0 0 2.8242 2h8a3 3 0 0 0 2.8262 -2h-13.65z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m3 13a1 1 0 0 0 1 1 1 1 0 0 0 1 -1h-2zm5 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm3 0a1 1 0 0 0 1 1 1 1 0 0 0 1 -1h-2z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m4 12a1 1 0 0 0 -1 1h2a1 1 0 0 0 -1 -1zm8 0a1 1 0 0 0 -1 1h2a1 1 0 0 0 -1 -1z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_path.svg b/editor/icons/dark/icon_path.svg
deleted file mode 100644
index 86c7fac35a..0000000000
--- a/editor/icons/dark/icon_path.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="3" cy="1049.4" r="2" fill="#ff5f5f" fill-opacity=".99608"/>
-<circle cx="13" cy="1039.4" r="2" fill="#ff5f5f" fill-opacity=".99608"/>
-<path d="m3 1049.4c0-9 10-1 10-10" fill="none" stroke="#ff5f5f" stroke-opacity=".99608" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_path_2d.svg b/editor/icons/dark/icon_path_2d.svg
deleted file mode 100644
index 06b6caa954..0000000000
--- a/editor/icons/dark/icon_path_2d.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff" fill-opacity=".98824">
-<circle cx="3" cy="1049.4" r="2"/>
-<circle cx="13" cy="1039.4" r="2"/>
-<path d="m12 1039.4c0 2.0648-0.49246 2.8244-1.1367 3.2754-0.64426 0.451-1.7129 0.6055-2.9629 0.7305s-2.6814 0.2205-3.9121 1.082c-1.2307 0.8615-1.9883 2.4769-1.9883 4.9121h2c0-2.0648 0.49246-2.8224 1.1367-3.2734 0.64426-0.451 1.7129-0.6055 2.9629-0.7305s2.6814-0.2205 3.9121-1.082c1.2307-0.8615 1.9883-2.4789 1.9883-4.9141h-2z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_path_follow.svg b/editor/icons/dark/icon_path_follow.svg
deleted file mode 100644
index c5b8176b75..0000000000
--- a/editor/icons/dark/icon_path_follow.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<circle cx="3" cy="1049.4" r="2"/>
-<path d="m12 1039.4c0 2.0648-0.49246 2.8244-1.1367 3.2754-0.64426 0.451-1.7129 0.6055-2.9629 0.7305s-2.6814 0.2205-3.9121 1.082c-1.2307 0.8615-1.9883 2.4769-1.9883 4.9121h2c0-2.0648 0.49246-2.8224 1.1367-3.2734 0.64426-0.451 1.7129-0.6055 2.9629-0.7305s2.6814-0.2205 3.9121-1.082c1.2307-0.8615 1.9883-2.4789 1.9883-4.9141h-2z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m10 1040.4h6l-3-4z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_path_follow_2d.svg b/editor/icons/dark/icon_path_follow_2d.svg
deleted file mode 100644
index e296fad421..0000000000
--- a/editor/icons/dark/icon_path_follow_2d.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff" fill-opacity=".98824">
-<circle cx="3" cy="1049.4" r="2"/>
-<path d="m12 1039.4c0 2.0648-0.49246 2.8244-1.1367 3.2754-0.64426 0.451-1.7129 0.6055-2.9629 0.7305s-2.6814 0.2205-3.9121 1.082c-1.2307 0.8615-1.9883 2.4769-1.9883 4.9121h2c0-2.0648 0.49246-2.8224 1.1367-3.2734 0.64426-0.451 1.7129-0.6055 2.9629-0.7305s2.6814-0.2205 3.9121-1.082c1.2307-0.8615 1.9883-2.4789 1.9883-4.9141h-2z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m10 1040.4h6l-3-4z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_pause.svg b/editor/icons/dark/icon_pause.svg
deleted file mode 100644
index 344cf12aa1..0000000000
--- a/editor/icons/dark/icon_pause.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 3a1.0001 1.0001 0 0 0 -1 1v8a1.0001 1.0001 0 0 0 1 1h2a1 1 0 0 0 1 -1v-8a1 1 0 0 0 -1 -1h-2zm6 0a1 1 0 0 0 -1 1v8a1 1 0 0 0 1 1h2a1.0001 1.0001 0 0 0 1 -1v-8a1.0001 1.0001 0 0 0 -1 -1h-2z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_pin.svg b/editor/icons/dark/icon_pin.svg
deleted file mode 100644
index c9988452de..0000000000
--- a/editor/icons/dark/icon_pin.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m3 1046.4h10l-2-3h-6z" fill-rule="evenodd"/>
-<path transform="translate(0 1036.4)" d="m4 1v1l1 1v3h6v-3l1-1v-1h-8z" fill-rule="evenodd"/>
-<rect x="7" y="1047.4" width="2" height="2"/>
-<path d="m7 1049.4 1 2 1-2h-2z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_pin_joint.svg b/editor/icons/dark/icon_pin_joint.svg
deleted file mode 100644
index 1a2b5dedb2..0000000000
--- a/editor/icons/dark/icon_pin_joint.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f">
-<path d="m1.9289 1043.3 7.0711 7.071l0.70711-3.5355-4.2426-4.2426z" fill-rule="evenodd"/>
-<path d="m9 1037.6-0.70711 0.7071v1.4142l-2.1213 2.1214 4.2426 4.2426 2.1213-2.1213h1.4142l0.70711-0.7071-5.6569-5.6569z" fill-rule="evenodd"/>
-<rect transform="matrix(.70711 .70711 -.70711 .70711 0 0)" x="743.08" y="737.35" width="2" height="2"/>
-<path d="m2.636 1048.2-0.70711 2.1213 2.1213-0.7071-1.4142-1.4142z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_pin_joint_2d.svg b/editor/icons/dark/icon_pin_joint_2d.svg
deleted file mode 100644
index 0afd1c1541..0000000000
--- a/editor/icons/dark/icon_pin_joint_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m9 1.2715l-0.70703 0.70703v1.4141l-2.1211 2.123 4.2422 4.2422 2.1211-2.1211h1.4141l0.70703-0.70703-5.6562-5.6582zm-3.5352 4.9512l-3.5352 0.70703 7.0703 7.0703 0.70703-3.5352-4.2422-4.2422zm-1.4141 4.2422l-1.4141 1.4141-0.70703 2.1211 2.1211-0.70703 1.4141-1.4141-1.4141-1.4141z" fill="#6d90ff" fill-opacity=".98824" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_pin_pressed.svg b/editor/icons/dark/icon_pin_pressed.svg
deleted file mode 100644
index c9988452de..0000000000
--- a/editor/icons/dark/icon_pin_pressed.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m3 1046.4h10l-2-3h-6z" fill-rule="evenodd"/>
-<path transform="translate(0 1036.4)" d="m4 1v1l1 1v3h6v-3l1-1v-1h-8z" fill-rule="evenodd"/>
-<rect x="7" y="1047.4" width="2" height="2"/>
-<path d="m7 1049.4 1 2 1-2h-2z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_plane.svg b/editor/icons/dark/icon_plane.svg
deleted file mode 100644
index 3e597419e2..0000000000
--- a/editor/icons/dark/icon_plane.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m1 1044.4 7 3 7-3-7-3z" fill="#4f4f4f" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_plane_mesh.svg b/editor/icons/dark/icon_plane_mesh.svg
deleted file mode 100644
index d90b6dd31e..0000000000
--- a/editor/icons/dark/icon_plane_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1048.4h12l-3-8h-6z" fill="none" stroke="#fea900" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_plane_shape.svg b/editor/icons/dark/icon_plane_shape.svg
deleted file mode 100644
index 27395b6a42..0000000000
--- a/editor/icons/dark/icon_plane_shape.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m1 1044.4 7 3 7-3-7-3z" fill="#a2d2ff" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_play.svg b/editor/icons/dark/icon_play.svg
deleted file mode 100644
index 531d704dac..0000000000
--- a/editor/icons/dark/icon_play.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m4 1048.4v-8l7 4z" fill="#4f4f4f" fill-rule="evenodd" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_play_backwards.svg b/editor/icons/dark/icon_play_backwards.svg
deleted file mode 100644
index 2dd2d63fe7..0000000000
--- a/editor/icons/dark/icon_play_backwards.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m12 1048.4v-8l-7 4z" fill="#4f4f4f" fill-rule="evenodd" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_play_custom.svg b/editor/icons/dark/icon_play_custom.svg
deleted file mode 100644
index bdb0138d6d..0000000000
--- a/editor/icons/dark/icon_play_custom.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m1 7v6a2 2 0 0 0 2 2h12v-8h-14zm3 1h4v1h4v5h-4-4v-5-1z"/>
-<path d="m0.71129 1040.4 0.28871 1.9791l2.2438-0.3273-0.81826-1.9018-1.7143 0.25zm3.6933-0.5387 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5775 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5774 0.81826 1.9018 1.7143-0.25-0.28871-1.9791-2.2438 0.3273z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_play_scene.svg b/editor/icons/dark/icon_play_scene.svg
deleted file mode 100644
index 4f0279b07c..0000000000
--- a/editor/icons/dark/icon_play_scene.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m1 7v6h2v2h12v-8h-14zm5 1l5 3-5 3v-6z"/>
-<path d="m0.71129 1040.4 0.28871 1.9791l2.2438-0.3273-0.81826-1.9018-1.7143 0.25zm3.6933-0.5387 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5775 0.81826 1.9018 1.9791-0.2887-0.81826-1.9018-1.9791 0.2887zm3.9581-0.5774 0.81826 1.9018 1.7143-0.25-0.28871-1.9791-2.2438 0.3273z"/>
-<circle cx="3" cy="1049.4" r="2"/>
-<circle cx="13" cy="1049.4" r="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_play_start.svg b/editor/icons/dark/icon_play_start.svg
deleted file mode 100644
index 2b917aab27..0000000000
--- a/editor/icons/dark/icon_play_start.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m7.0001 1048.4v-8l7 4z" fill-rule="evenodd" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-<path d="m3 1039.4c0.55226 1e-4 0.99994 0.4477 1 1v8c-5.5e-5 0.5523-0.44774 0.9999-1 1h-1v-1h-1v-8h1v-1z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle transform="scale(-1,1)" cx="-2" cy="1040.4" r="1"/>
-<circle transform="scale(-1,1)" cx="-2" cy="1048.4" r="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_play_start_backwards.svg b/editor/icons/dark/icon_play_start_backwards.svg
deleted file mode 100644
index 8fb7563169..0000000000
--- a/editor/icons/dark/icon_play_start_backwards.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m8.9999 1048.4v-8l-7 4z" fill-rule="evenodd" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-<path d="m13 1039.4c-0.55226 1e-4 -0.99994 0.4477-1 1v8c5.5e-5 0.5523 0.44774 0.9999 1 1h1v-1h1v-8h-1v-1z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle cx="14" cy="1040.4" r="1"/>
-<circle cx="14" cy="1048.4" r="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_polygon_2_d.svg b/editor/icons/dark/icon_polygon_2_d.svg
deleted file mode 100644
index e1b5bc82aa..0000000000
--- a/editor/icons/dark/icon_polygon_2_d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#6d90ff" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_polygon_path_finder.svg b/editor/icons/dark/icon_polygon_path_finder.svg
deleted file mode 100644
index d8e836b13b..0000000000
--- a/editor/icons/dark/icon_polygon_path_finder.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1c-0.55226 5.52e-5 -0.99994 0.44774-1 1v1h2v-2h-1zm3 0v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h1.4141l0.29297-0.29297c0.62956-0.62999 0.18361-1.7067-0.70703-1.707h-1zm-12 4v2h2v-2h-2zm11 2l-3 8 3-2 3 2-3-8zm-11 2v2h2v-2h-2zm0 4v1c5.52e-5 0.55226 0.44774 0.99994 1 1h1v-2h-2zm4 0v2h1.9023c-7.835e-4 -0.2513 0.043539-0.50069 0.13086-0.73633l0.47461-1.2637h-2.5078z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_popup.svg b/editor/icons/dark/icon_popup.svg
deleted file mode 100644
index 1aa7da9c64..0000000000
--- a/editor/icons/dark/icon_popup.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm4 2h2v6h-2v-6zm0 8h2v2h-2v-2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_popup_dialog.svg b/editor/icons/dark/icon_popup_dialog.svg
deleted file mode 100644
index 5b6988d099..0000000000
--- a/editor/icons/dark/icon_popup_dialog.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.8954-2 2v1h14v-1c0-1.1046-0.89543-2-2-2h-10zm9 1h1v1h-1v-1zm-11 3v8c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-8h-14zm6 1h2v5h-2v-5zm0 6h2v2h-2v-2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_popup_menu.svg b/editor/icons/dark/icon_popup_menu.svg
deleted file mode 100644
index 1f8f15f252..0000000000
--- a/editor/icons/dark/icon_popup_menu.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m2 6a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1 -1v-7a1 1 0 0 0 -1 -1h-12zm1 2h10v2h-10v-2zm0 3h10v2h-10v-2z"/>
-<path transform="translate(0 1036.4)" d="m1 1v4h6v-4h-6zm1 1h4l-2 2-2-2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_popup_panel.svg b/editor/icons/dark/icon_popup_panel.svg
deleted file mode 100644
index 7955c624b3..0000000000
--- a/editor/icons/dark/icon_popup_panel.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m2 6c-0.55228 0-1 0.44772-1 1v7c0 0.55228 0.44772 1 1 1h12c0.55228 0 1-0.44772 1-1v-7c0-0.55228-0.44772-1-1-1z"/>
-<path transform="translate(0 1036.4)" d="m1 1v4h6v-4h-6zm1 1h4l-2 2-2-2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_portal.svg b/editor/icons/dark/icon_portal.svg
deleted file mode 100644
index 58aa904305..0000000000
--- a/editor/icons/dark/icon_portal.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a5 7 0 0 0 -5 7 5 7 0 0 0 5 7 5 7 0 0 0 5 -7 5 7 0 0 0 -5 -7zm0 2a3 5 0 0 1 3 5 3 5 0 0 1 -3 5 3 5 0 0 1 -3 -5 3 5 0 0 1 3 -5z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_position_2d.svg b/editor/icons/dark/icon_position_2d.svg
deleted file mode 100644
index 35bcb9b389..0000000000
--- a/editor/icons/dark/icon_position_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v4h2v-4h-2zm-6 6v2h4v-2h-4zm10 0v2h4v-2h-4zm-4 4v4h2v-4h-2z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_position_3d.svg b/editor/icons/dark/icon_position_3d.svg
deleted file mode 100644
index 89cbe40ffc..0000000000
--- a/editor/icons/dark/icon_position_3d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v4h2v-4h-2zm-6 6v2h4v-2h-4zm10 0v2h4v-2h-4zm-4 4v4h2v-4h-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_prism_mesh.svg b/editor/icons/dark/icon_prism_mesh.svg
deleted file mode 100644
index c2a64904e9..0000000000
--- a/editor/icons/dark/icon_prism_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9824 1.002a1.0001 1.0001 0 0 0 -0.81445 0.44336l-5.9727 8.9609-0.027344 0.039062a1 1 0 0 0 -0.0625 0.10742 1 1 0 0 0 0.44727 1.3418l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1 1 0 0 0 0.44726 -1.3418 1 1 0 0 0 -0.0625 -0.10742l-6-9a1.0001 1.0001 0 0 0 -0.84961 -0.44336zm-0.98242 4.3008v7.0801l-3.5391-1.7715 3.5391-5.3086zm2 0l3.5391 5.3086-3.5391 1.7715v-7.0801z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fea900" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_procedural_sky.svg b/editor/icons/dark/icon_procedural_sky.svg
deleted file mode 100644
index b3bc927409..0000000000
--- a/editor/icons/dark/icon_procedural_sky.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="8" x2="8" y1="1040.4" y2="1050.4" gradientUnits="userSpaceOnUse">
-<stop stop-color="#1ec3ff" offset="0"/>
-<stop stop-color="#b2e1ff" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1037.4)">
-<path d="m8 1040.4a7 7 0 0 0 -7 7 7 7 0 0 0 0.68555 3h12.631a7 7 0 0 0 0.68359 -3 7 7 0 0 0 -7 -7z" fill="url(#a)"/>
-<rect x="2" y="1047.4" width="3" height="2" ry="1" fill="#fff"/>
-<rect x="7" y="1045.4" width="4" height="2" ry="1" fill="#fff"/>
-<rect x="9" y="1044.4" width="4" height="2" ry="1" fill="#fff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_1.svg b/editor/icons/dark/icon_progress_1.svg
deleted file mode 100644
index 8b2d9e8b45..0000000000
--- a/editor/icons/dark/icon_progress_1.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".99608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".19608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".19608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".19608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".19608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".19608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".19608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_2.svg b/editor/icons/dark/icon_progress_2.svg
deleted file mode 100644
index 8f7c358ba1..0000000000
--- a/editor/icons/dark/icon_progress_2.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".19608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".19608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".19608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".99608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".19608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".19608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".19608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_3.svg b/editor/icons/dark/icon_progress_3.svg
deleted file mode 100644
index 78bd84d642..0000000000
--- a/editor/icons/dark/icon_progress_3.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".19608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".19608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".19608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".19608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".19608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".99608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".19608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_4.svg b/editor/icons/dark/icon_progress_4.svg
deleted file mode 100644
index 7283ad79cb..0000000000
--- a/editor/icons/dark/icon_progress_4.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".19608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".19608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".19608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".19608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".19608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".19608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".19608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_5.svg b/editor/icons/dark/icon_progress_5.svg
deleted file mode 100644
index 2651292260..0000000000
--- a/editor/icons/dark/icon_progress_5.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".19608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".19608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".19608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".19608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".19608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".19608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".99608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_6.svg b/editor/icons/dark/icon_progress_6.svg
deleted file mode 100644
index 1b44ececc5..0000000000
--- a/editor/icons/dark/icon_progress_6.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".19608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".19608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".19608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".19608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".99608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".19608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".19608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_7.svg b/editor/icons/dark/icon_progress_7.svg
deleted file mode 100644
index 7560a605fb..0000000000
--- a/editor/icons/dark/icon_progress_7.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".19608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".19608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".99608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".19608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".19608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".19608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".19608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_8.svg b/editor/icons/dark/icon_progress_8.svg
deleted file mode 100644
index d98826dfba..0000000000
--- a/editor/icons/dark/icon_progress_8.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273 0.4258l2.1582-2.1582a7 7 0 0 0 -3.1855 -1.3223z" fill-opacity=".19608"/>
-<path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273 -0.4277v-3.0508z" fill-opacity=".99608"/>
-<path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 0.42578 -1.0273l-2.1582-2.1582z" fill-opacity=".19608"/>
-<path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 0.42774 1.0273h3.0508a7 7 0 0 0 -1.3203 -3.1855z" fill-opacity=".19608"/>
-<path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -0.42773 -1.0273h-3.0508z" fill-opacity=".19608"/>
-<path d="m11.867 1045.4a4 4 0 0 1 -0.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223 -3.1855h-3.0547z" fill-opacity=".19608"/>
-<path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273 -0.4258z" fill-opacity=".19608"/>
-<path d="m10.027 1047.8a4 4 0 0 1 -1.0273 0.4277v3.0508a7 7 0 0 0 3.1855 -1.3203l-2.1582-2.1582z" fill-opacity=".19608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_progress_bar.svg b/editor/icons/dark/icon_progress_bar.svg
deleted file mode 100644
index 3da8ff43b8..0000000000
--- a/editor/icons/dark/icon_progress_bar.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 3c-1.1046 0-2 0.89543-2 2v6c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-6c0-1.1046-0.89543-2-2-2zm0 2h10v6h-10z"/>
-<rect x="4" y="1042.4" width="1" height="4"/>
-<rect x="6" y="1042.4" width="1" height="4"/>
-<rect x="8" y="1042.4" width="1" height="4"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_proximity_group.svg b/editor/icons/dark/icon_proximity_group.svg
deleted file mode 100644
index 32145798e3..0000000000
--- a/editor/icons/dark/icon_proximity_group.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<rect x="1" y="1037.4" width="2" height="14"/>
-<rect x="1" y="1037.4" width="14" height="2"/>
-<rect transform="scale(-1)" x="-15" y="-1051.4" width="2" height="14"/>
-<rect transform="scale(-1)" x="-15" y="-1051.4" width="14" height="2"/>
-<circle cx="10.5" cy="1041.9" r="1.5"/>
-<circle cx="5.5" cy="1046.9" r="1.5"/>
-<circle cx="10.5" cy="1046.9" r="1.5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_quad.svg b/editor/icons/dark/icon_quad.svg
deleted file mode 100644
index 6d8c149558..0000000000
--- a/editor/icons/dark/icon_quad.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 10 2h2 12v-2-12h-12-2zm3.4141 2h8.5859v8.5859l-8.5859-8.5859zm-1.4141 1.4141l8.5859 8.5859h-8.5859v-8.5859z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_quad_mesh.svg b/editor/icons/dark/icon_quad_mesh.svg
deleted file mode 100644
index cf7ba9ac0d..0000000000
--- a/editor/icons/dark/icon_quad_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m15 1037.4v14h-14v-14zm-2 2h-8.5859l8.5859 8.5859zm-10 1.4141v8.5859h8.5859z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fea900" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_quat.svg b/editor/icons/dark/icon_quat.svg
deleted file mode 100644
index c5c9006d66..0000000000
--- a/editor/icons/dark/icon_quat.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m7 1v6h2v-6h-2zm0 12v2h2v-2h-2z"/>
-<path d="m11 1039.8v2.0137a5 2 0 0 1 2 1.5957 5 2 0 0 1 -5 2 5 2 0 0 1 -5 -2 5 2 0 0 1 2 -1.5977v-2.0097a7 4 0 0 0 -4 3.6074 7 4 0 0 0 7 4 7 4 0 0 0 7 -4 7 4 0 0 0 -4 -3.6094z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_range.svg b/editor/icons/dark/icon_range.svg
deleted file mode 100644
index e19ab80f7d..0000000000
--- a/editor/icons/dark/icon_range.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<rect x="1" y="1039.4" width="2" height="10"/>
-<rect x="1" y="1043.4" width="13" height="2"/>
-<rect x="13" y="1039.4" width="2" height="10"/>
-<rect x="5" y="1041.4" width="2" height="6"/>
-<rect x="9" y="1041.4" width="2" height="6"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rating_no_star.svg b/editor/icons/dark/icon_rating_no_star.svg
deleted file mode 100644
index d81408b637..0000000000
--- a/editor/icons/dark/icon_rating_no_star.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g fill="#c3ae65">
-<path transform="translate(0 1036.4)" d="m8 1.7246-2.375 4.0977-4.625 1.0977 3.2363 3.4063-0.35938 4.6738 4.1387-1.9766 4.1582 1.9414-0.39648-4.6523 3.2227-3.3926-4.625-1.0977z" fill="#fea900" fill-opacity=".58824"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rating_star.svg b/editor/icons/dark/icon_rating_star.svg
deleted file mode 100644
index 3a1e344d4b..0000000000
--- a/editor/icons/dark/icon_rating_star.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8 1038.1-2.3741 4.0973-4.6259 1.0978l3.2361 3.4074-0.35866 4.6735 4.1389-1.9766 4.1572 1.9421-0.39534-4.6532 3.2218-3.3932-4.6259-1.0978-2.3741-4.0973z" fill="#fea900"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_ray_cast.svg b/editor/icons/dark/icon_ray_cast.svg
deleted file mode 100644
index 656c02d018..0000000000
--- a/editor/icons/dark/icon_ray_cast.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<rect x="7" y="1037.4" width="2" height="9"/>
-<path d="m4 1046.4h8l-4 5z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_ray_cast_2d.svg b/editor/icons/dark/icon_ray_cast_2d.svg
deleted file mode 100644
index 434d8cc62a..0000000000
--- a/editor/icons/dark/icon_ray_cast_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v9h-3l4 5 4-5h-3v-9h-2z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_ray_shape.svg b/editor/icons/dark/icon_ray_shape.svg
deleted file mode 100644
index 4591b0a3f9..0000000000
--- a/editor/icons/dark/icon_ray_shape.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-rule="evenodd">
-<path d="m8 1051.4-2-2v-7l2 2z" fill="#a2d2ff"/>
-<path d="m8 1047.9-2-1.5v-4l2 2z" fill="#2998ff"/>
-<path d="m8 1037.4-6 5 6 4z" fill="#a2d2ff"/>
-<path d="m8 1051.4 2-2v-7l-2 2z" fill="#2998ff"/>
-<path d="m8 1037.4 6 5-6 4z" fill="#2998ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_ray_shape_2d.svg b/editor/icons/dark/icon_ray_shape_2d.svg
deleted file mode 100644
index 89533b8407..0000000000
--- a/editor/icons/dark/icon_ray_shape_2d.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#68b6ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
-<path d="m8 1038.4v12"/>
-<path d="m5 1047.4 3 3 3-3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rayito.svg b/editor/icons/dark/icon_rayito.svg
deleted file mode 100644
index 4e1e90eaf9..0000000000
--- a/editor/icons/dark/icon_rayito.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#fea900">
-<rect transform="matrix(1 0 -.14142 .98995 0 0)" x="152.19" y="1047.9" width="7" height="7.0711"/>
-<path d="m6 1043.4h8l-9 8z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_real.svg b/editor/icons/dark/icon_real.svg
deleted file mode 100644
index 68f477f727..0000000000
--- a/editor/icons/dark/icon_real.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#cf68ea">
-<rect x="3" y="1040.4" width="2" height="11"/>
-<rect x="3" y="1039.4" width="4" height="2"/>
-<path transform="translate(0 1038.4)" d="m7 1v2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2v2a4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4z"/>
-<rect x="3" y="1045.4" width="4" height="2"/>
-<rect transform="rotate(90)" x="1049.4" y="-12" width="2" height="2"/>
-<path transform="translate(0 1038.4)" d="m8 7v2a2 2 0 0 1 2 2h2a4 4 0 0 0 -4 -4z"/>
-<rect transform="rotate(90)" x="1045.4" y="-8" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rectangle_shape_2d.svg b/editor/icons/dark/icon_rectangle_shape_2d.svg
deleted file mode 100644
index d5cf89f5dc..0000000000
--- a/editor/icons/dark/icon_rectangle_shape_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="2" y="1040.4" width="12" height="8" rx="1.7383e-5" ry="1.7383e-5" color="#000000" fill="none" stroke="#68b6ff" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_reference_rect.svg b/editor/icons/dark/icon_reference_rect.svg
deleted file mode 100644
index 0bc52b44c8..0000000000
--- a/editor/icons/dark/icon_reference_rect.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<rect x="1" y="1037.4" width="2" height="2"/>
-<rect x="13" y="1037.4" width="2" height="2"/>
-<rect x="4" y="1037.4" width="8" height="2"/>
-<rect x="4" y="1049.4" width="8" height="2"/>
-<rect x="13" y="1049.4" width="2" height="2"/>
-<rect x="1" y="1049.4" width="2" height="2"/>
-<rect transform="rotate(90)" x="1040.4" y="-3" width="8" height="2"/>
-<rect transform="rotate(90)" x="1040.4" y="-15" width="8" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_reflection_probe.svg b/editor/icons/dark/icon_reflection_probe.svg
deleted file mode 100644
index daafbff1ea..0000000000
--- a/editor/icons/dark/icon_reflection_probe.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-6 3a1.0001 1.0001 0 0 0 -0.55273 0.89453v6a1.0001 1.0001 0 0 0 0.55273 0.89453l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.89453v-6a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-6-3a1.0001 1.0001 0 0 0 -0.48438 -0.10352zm-0.96289 2.6172v8.7637l-4-2v-4.7637l4-2zm2 0l4 2v4.7637l-4 2v-8.7637z" color="#000000" color-rendering="auto" fill="#ff5f5f" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_region_edit.svg b/editor/icons/dark/icon_region_edit.svg
deleted file mode 100644
index 4cd5fcb8ad..0000000000
--- a/editor/icons/dark/icon_region_edit.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="6" y="1042.4" width="6" height="6"/>
-<rect x="6" y="1037.4" width="6" height="4" fill-opacity=".32549"/>
-<rect x="1" y="1037.4" width="4" height="4" fill-opacity=".32549"/>
-<rect x="1" y="1042.4" width="4" height="6" fill-opacity=".32549"/>
-<rect x="1" y="1049.4" width="4" height="2" fill-opacity=".32549"/>
-<rect x="6" y="1049.4" width="6" height="2" fill-opacity=".32549"/>
-<rect x="13" y="1042.4" width="2" height="6" fill-opacity=".32549"/>
-<rect x="13" y="1037.4" width="2" height="4" fill-opacity=".32549"/>
-<rect x="13" y="1049.4" width="2" height="2" fill-opacity=".32549"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_reload.svg b/editor/icons/dark/icon_reload.svg
deleted file mode 100644
index 4c5f0e7dbc..0000000000
--- a/editor/icons/dark/icon_reload.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4 -4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6z"/>
-<path transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)" d="m4.118 1048.3-1.6771-0.9683-1.6771-0.9682 1.6771-0.9683 1.6771-0.9682-1e-7 1.9365z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_reload_small.svg b/editor/icons/dark/icon_reload_small.svg
deleted file mode 100644
index 5de3537136..0000000000
--- a/editor/icons/dark/icon_reload_small.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path d="m8 1039.4a6 6 0 0 0 -6 6h2a4 4 0 0 1 4 -4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6z"/>
-<path transform="matrix(0 -1.1926 1.5492 0 -1618 1050.3)" d="m4.118 1048.3-1.6771-0.9683-1.6771-0.9682 1.6771-0.9683 1.6771-0.9682-1e-7 1.9365z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_remote.svg b/editor/icons/dark/icon_remote.svg
deleted file mode 100644
index 5381ba07da..0000000000
--- a/editor/icons/dark/icon_remote.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<circle cx="8" cy="1043.4" r="2"/>
-<rect x="7" y="1044.4" width="2" height="7"/>
-<path transform="translate(0 1036.4)" d="m8.0879 1a6 6 0 0 0 -4.3301 1.7578 6 6 0 0 0 0 8.4844l1.416-1.416a4 4 0 0 1 -1.1738 -2.8262 4 4 0 0 1 4 -4 4 4 0 0 1 4 4 4 4 0 0 1 -1.1738 2.8262l1.416 1.416a6 6 0 0 0 0 -8.4844 6 6 0 0 0 -4.1543 -1.7578z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_remote_transform.svg b/editor/icons/dark/icon_remote_transform.svg
deleted file mode 100644
index cfeadc9bd2..0000000000
--- a/editor/icons/dark/icon_remote_transform.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m12 1047.4a4 4 0 0 1 -2 3.4641 4 4 0 0 1 -4 0 4 4 0 0 1 -2 -3.4641h4z" fill="#ff5f5f"/>
-<rect x="7" y="1045.4" width="2" height="4" ry="1" fill="#ff5f5f"/>
-<path d="m1.9378 1041.9a7 7 0 0 1 6.0622 -3.5 7 7 0 0 1 6.0622 3.5" fill="none" stroke="#ff5f5f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m5.1022 1044.6a3 3 0 0 1 2.8978 -2.2235 3 3 0 0 1 2.8978 2.2235" fill="none" stroke="#ff5f5f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_remote_transform_2d.svg b/editor/icons/dark/icon_remote_transform_2d.svg
deleted file mode 100644
index 443a21382b..0000000000
--- a/editor/icons/dark/icon_remote_transform_2d.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m12 1047.4a4 4 0 0 1 -2 3.4641 4 4 0 0 1 -4 0 4 4 0 0 1 -2 -3.4641h4z" fill="#6d90ff" fill-opacity=".98824"/>
-<rect x="7" y="1045.4" width="2" height="4" ry="1" fill="#6d90ff" fill-opacity=".98824"/>
-<path d="m1.9378 1041.9a7 7 0 0 1 6.0622 -3.5 7 7 0 0 1 6.0622 3.5" fill="none" stroke="#6d90ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m5.1022 1044.6a3 3 0 0 1 2.8978 -2.2235 3 3 0 0 1 2.8978 2.2235" fill="none" stroke="#6d90ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_remove.svg b/editor/icons/dark/icon_remove.svg
deleted file mode 100644
index 4d461e251e..0000000000
--- a/editor/icons/dark/icon_remove.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m2 5v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2v-8h-12zm1 2h2v6h-2v-6zm4 0h2v6h-2v-6zm4 0h2v6h-2v-6z"/>
-<rect x="1" y="1038.4" width="14" height="2"/>
-<rect x="5" y="1037.4" width="6" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rename.svg b/editor/icons/dark/icon_rename.svg
deleted file mode 100644
index 3c013a4e3b..0000000000
--- a/editor/icons/dark/icon_rename.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 2v2h2v8h-2v2h2c0.55228 0 1-0.4477 1-1 0 0.5523 0.44772 1 1 1h2v-2h-2v-8h2v-2h-2c-0.55228 0-1 0.44772-1 1 0-0.55228-0.44772-1-1-1h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_reparent.svg b/editor/icons/dark/icon_reparent.svg
deleted file mode 100644
index 03094ad341..0000000000
--- a/editor/icons/dark/icon_reparent.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 2a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v5.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -0.72852 -0.73047v-5.541a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m9 1l-4 3 4 3v-2a3 3 0 0 1 3 3v2h2v-2a5 5 0 0 0 -5 -5v-2z" fill="#00f010"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_resource_preloader.svg b/editor/icons/dark/icon_resource_preloader.svg
deleted file mode 100644
index c7d0b1b542..0000000000
--- a/editor/icons/dark/icon_resource_preloader.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g fill="#4f4f4f" fill-rule="evenodd">
-<path transform="translate(0 1036.4)" d="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-6 3a1.0001 1.0001 0 0 0 -0.55273 0.89453v6a1.0001 1.0001 0 0 0 0.55273 0.89453l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.89453v-6a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-6-3a1.0001 1.0001 0 0 0 -0.48438 -0.10352zm0.037109 2.1172l3.7637 1.8809-3.7637 1.8828-3.7637-1.8828 3.7637-1.8809zm-5 3.5l4 2v3.7637l-4-2v-3.7637zm10 0v3.7637l-4 2v-3.7637l4-2z" color="#000000" color-rendering="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<path d="m11 1042.4-6-3-3 2 6 3z"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rich_text_label.svg b/editor/icons/dark/icon_rich_text_label.svg
deleted file mode 100644
index 531909d92f..0000000000
--- a/editor/icons/dark/icon_rich_text_label.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<rect x="1" y="1037.4" width="8" height="2"/>
-<rect x="1" y="1041.4" width="2" height="2"/>
-<rect x="5" y="1041.4" width="4" height="2"/>
-<rect x="1" y="1045.4" width="8" height="2"/>
-<rect x="1" y="1049.4" width="4" height="2"/>
-<rect x="7" y="1049.4" width="2" height="2"/>
-<path d="m12 1048.4h-2l3 3 3-3h-2v-8h2l-3-3-3 3h2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rigid_body.svg b/editor/icons/dark/icon_rigid_body.svg
deleted file mode 100644
index 87fff0b0e4..0000000000
--- a/editor/icons/dark/icon_rigid_body.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 0.035156 0.69922 7 7 0 0 0 0.27734 1.3691 7 7 0 0 0 0.91016 1.8848 7 7 0 0 0 0.30273 0.4082c7.85e-4 -0.00256 0.0011667-0.005252 0.0019532-0.007812a7 7 0 0 0 5.4727 2.6465 7 7 0 0 0 3.2422 -0.80273c0.001375 3.93e-4 0.002531 0.00156 0.003906 0.001953a7 7 0 0 0 0.035156 -0.021485 7 7 0 0 0 0.42578 -0.25 7 7 0 0 0 0.16992 -0.10352 7 7 0 0 0 0.36914 -0.26953 7 7 0 0 0 0.20508 -0.15625 7 7 0 0 0 0.3418 -0.30859 7 7 0 0 0 0.16406 -0.1543 7 7 0 0 0 0.33008 -0.36133 7 7 0 0 0 0.14062 -0.16016 7 7 0 0 0 0.27734 -0.37305 7 7 0 0 0 0.13867 -0.19531 7 7 0 0 0 0.21875 -0.36133 7 7 0 0 0 0.14258 -0.25 7 7 0 0 0 0.15625 -0.33398 7 7 0 0 0 0.13867 -0.31055 7 7 0 0 0 0.10742 -0.30859 7 7 0 0 0 0.11914 -0.35352 7 7 0 0 0 0.087891 -0.36914 7 7 0 0 0 0.066406 -0.29297 7 7 0 0 0 0.056641 -0.40039 7 7 0 0 0 0.037109 -0.3125 7 7 0 0 0 0.025391 -0.55273 7 7 0 0 0 -4.3848 -6.4883 7 7 0 0 0 -0.007812 -0.0039063 7 7 0 0 0 -0.001953 0 7 7 0 0 0 -0.61523 -0.21289 7 7 0 0 0 -0.044922 -0.015625 7 7 0 0 0 -0.0058594 -0.0019531 7 7 0 0 0 -0.55078 -0.13086 7 7 0 0 0 -0.14062 -0.03125 7 7 0 0 0 -0.55078 -0.072266 7 7 0 0 0 -0.14258 -0.017578 7 7 0 0 0 -0.55469 -0.025391zm1.9512 1.334a6 6 0 0 1 4.0488 5.666h-7a2 2 0 0 1 -0.94922 1.6992c1.345 2.0268 2.6013 3.2645 3.8965 3.9688a6 6 0 0 1 -1.9473 0.33203 6 6 0 0 1 -5.0547 -2.7695c0.23771-0.5785 0.50336-1.1403 0.82617-1.6563a2 2 0 0 1 -0.77148 -1.5742h-1a6 6 0 0 1 1.123 -3.4863c0.14632 0.65093 0.35776 1.2833 0.68359 1.8848a2 2 0 0 1 1.1934 -0.39844 2 2 0 0 1 1.0508 0.30078c1.3464-2.0289 2.6038-3.2631 3.9004-3.9668z"/>
-<circle cx="5" cy="1044.4" r="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rigid_body_2d.svg b/editor/icons/dark/icon_rigid_body_2d.svg
deleted file mode 100644
index 5e88969b81..0000000000
--- a/editor/icons/dark/icon_rigid_body_2d.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m8 1037.4a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1 -6 6 6 6 0 0 1 -6 -6 6 6 0 0 1 6 -6z" fill="#6d90ff" fill-opacity=".98824"/>
-<path d="m8 1037.4a7 7 0 0 0 -5.0879 2.2051c0.10495 1.1207 0.35417 2.1959 0.89453 3.1933a2 2 0 0 1 1.1934 -0.3984 2 2 0 0 1 1.0508 0.3008c1.7873-2.6932 3.4181-3.9904 5.1914-4.4981a7 7 0 0 0 -3.2422 -0.8027zm-7 7a7 7 0 0 0 1.5254 4.3613c0.30281-0.9877 0.71628-1.9403 1.2461-2.7871a2 2 0 0 1 -0.77148 -1.5742h-2zm6 0a2 2 0 0 1 -0.94922 1.6992c1.7887 2.6953 3.4204 3.9932 5.1953 4.5a7 7 0 0 0 3.7539 -6.1992h-8z" fill="#6d90ff" fill-opacity=".98824"/>
-<circle cx="5" cy="1044.4" r="2" fill="#6d90ff" fill-opacity=".98824"/>
-<path d="m45 1037.4a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1 -6 6 6 6 0 0 1 -6 -6 6 6 0 0 1 6 -6z" fill="#6d90ff" fill-opacity=".98824"/>
-<path d="m38 1044.4c5 0.01 9 0.01 14 0-2-2.9934-5-4-7-4s-5 1.0066-7 4z" fill="#6d90ff" fill-opacity=".98824" fill-rule="evenodd"/>
-<path d="m38 1044.4c0 3.866 3.134 7 7 7s7-3.134 7-7c-2 2.9933-5 4-7 4s-5-1.0067-7-4z" fill="#a3b6f2"/>
-<path d="m-9 1037.4a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1 -6 6 6 6 0 0 1 -6 -6 6 6 0 0 1 6 -6z" fill="#a3b6f2"/>
-<circle cx="-9" cy="1044.4" r="2" fill="#a3b6f2"/>
-<path d="m-9 1037.4a7 7 0 0 0 -3.5 0.9375l3.5 6.0625 3.5-6.0625a7 7 0 0 0 -3.5 -0.9375zm0 7 3.5 6.0625a7 7 0 0 0 2.5625 -2.5625 7 7 0 0 0 0.9375 -3.5h-7zh-7a7 7 0 0 0 0.9375 3.5 7 7 0 0 0 2.5625 2.5625l3.5-6.0625z" fill="#a3b6f2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_room.svg b/editor/icons/dark/icon_room.svg
deleted file mode 100644
index d5d32f35d0..0000000000
--- a/editor/icons/dark/icon_room.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-6 3a1.0001 1.0001 0 0 0 -0.55273 0.89453v6a1.0001 1.0001 0 0 0 0.55273 0.89453l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.89453v-6a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-6-3a1.0001 1.0001 0 0 0 -0.48438 -0.10352zm1.0371 2.6172l4 2v3.7637l-4-2v-3.7637zm-1 5.5l3.7637 1.8809-3.7637 1.8828-3.7637-1.8828 3.7637-1.8809z" color="#000000" color-rendering="auto" fill="#ff5f5f" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_room_bounds.svg b/editor/icons/dark/icon_room_bounds.svg
deleted file mode 100644
index 505b10aebf..0000000000
--- a/editor/icons/dark/icon_room_bounds.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v1 1h1v-1h1v-1h-1-1zm12 0v1h1v1h1v-1-1h-1-1zm-5.0371 0.0019531a1.0001 1.0001 0 0 0 -0.41016 0.10352l-6 3a1.0001 1.0001 0 0 0 -0.55273 0.89453v6a1.0001 1.0001 0 0 0 0.55273 0.89453l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.89453v-6a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-6-3a1.0001 1.0001 0 0 0 -0.48438 -0.10352zm1.0371 2.6172l4 2v3.7637l-4-2v-3.7637zm-1 5.5l3.7637 1.8809-3.7637 1.8828-3.7637-1.8828 3.7637-1.8809zm-7 3.8809v1 1h1 1v-1h-1v-1h-1zm13 0v1h-1v1h1 1v-1-1h-1z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rotate_0.svg b/editor/icons/dark/icon_rotate_0.svg
deleted file mode 100644
index 0afebb7d1e..0000000000
--- a/editor/icons/dark/icon_rotate_0.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="7" y="1038.4" width="2" height="7"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5 -5 5 5 0 0 1 5 -5z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rotate_180.svg b/editor/icons/dark/icon_rotate_180.svg
deleted file mode 100644
index e6d2d8806a..0000000000
--- a/editor/icons/dark/icon_rotate_180.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m8 1038.4a6 6 0 0 1 6 6h-6z"/>
-<rect x="7" y="1038.4" width="2" height="7"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5 -5 5 5 0 0 1 5 -5z"/>
-<rect transform="scale(-1)" x="-9" y="-1050.4" width="2" height="7"/>
-<path d="m14 1044.4a6 6 0 0 1 -6 6v-6z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rotate_270.svg b/editor/icons/dark/icon_rotate_270.svg
deleted file mode 100644
index 0b1ac39651..0000000000
--- a/editor/icons/dark/icon_rotate_270.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m8 1038.4a6 6 0 0 1 6 6h-6z"/>
-<rect x="7" y="1038.4" width="2" height="7"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5 -5 5 5 0 0 1 5 -5z"/>
-<rect transform="rotate(-90)" x="-1045.4" y="2" width="2" height="7"/>
-<path d="m8 1050.4a6 6 0 0 1 -6 -6h6z"/>
-<path d="m14 1044.4a6 6 0 0 1 -6 6v-6z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_rotate_90.svg b/editor/icons/dark/icon_rotate_90.svg
deleted file mode 100644
index 513ef5388c..0000000000
--- a/editor/icons/dark/icon_rotate_90.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m8 1038.4a6 6 0 0 1 6 6h-6z"/>
-<rect x="7" y="1038.4" width="2" height="7"/>
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5 -5 5 5 0 0 1 5 -5z"/>
-<rect transform="rotate(90)" x="1043.4" y="-14" width="2" height="7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sample_library.svg b/editor/icons/dark/icon_sample_library.svg
deleted file mode 100644
index 5292330aef..0000000000
--- a/editor/icons/dark/icon_sample_library.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff4040">
-<path transform="translate(0 1036.4)" d="m9 8v1 5 1h5c0.55228 0 1-0.44772 1-1v-5c0-0.55228-0.44772-1-1-1v4l-1-1-1 1v-4z"/>
-<path d="m7.0215 1037.4a1.0001 1.0001 0 0 0 -1 0.875l-0.58984 4.7226-0.52344-1.0468a1.0001 1.0001 0 0 0 -0.89453 -0.5528h-2a1.0001 1.0001 0 1 0 0 2h1.3828l1.7227 3.4473a1.0001 1.0001 0 0 0 1.8867 -0.3223l0.58984-4.7226 0.52344 1.0449a1.0001 1.0001 0 0 0 0.89453 0.5527h3a1.0001 1.0001 0 1 0 0 -2h-2.3809l-1.7246-3.4472a1.0001 1.0001 0 0 0 -0.88672 -0.5508z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_save.svg b/editor/icons/dark/icon_save.svg
deleted file mode 100644
index 831cb8b614..0000000000
--- a/editor/icons/dark/icon_save.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-8l-4-4zh8v6h-8zm5 8c1.1046 0 2 0.89543 2 2 0 1.1046-0.89543 2-2 2s-2-0.89543-2-2c0-1.1046 0.89543-2 2-2z"/>
-<rect x="4" y="1037.4" width="3" height="5"/>
-<path d="m11 1037.4h1l3 3v2h-4z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_script.svg b/editor/icons/dark/icon_script.svg
deleted file mode 100644
index 04c70b6985..0000000000
--- a/editor/icons/dark/icon_script.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 1v1a1 1 0 0 0 -1 1v10h-1v-2h-2v2a1 1 0 0 0 0.5 0.86523 1 1 0 0 0 0.5 0.13477v1h7a2 2 0 0 0 2 -2v-8h3v-2a2 2 0 0 0 -2 -2h-7z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m6 1c-1.1046 0-2 0.89543-2 2v7h-2-1v1 2c0 1.1046 0.89543 2 2 2s2-0.89543 2-2v-10c0-0.55228 0.44772-1 1-1s1 0.44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-0.89543-2-2-2zm-4 10h2v2c0 0.55228-0.44772 1-1 1s-1-0.44772-1-1v-2z" fill="#000000"/>
-<circle cx="3" cy="1048.4" rx="1" ry="1" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_script_create.svg b/editor/icons/dark/icon_script_create.svg
deleted file mode 100644
index aa9d692d14..0000000000
--- a/editor/icons/dark/icon_script_create.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 1v1c-0.55228 0-1 0.44772-1 1v10h-1v-2h-2v2c2.826e-4 0.35698 0.19084 0.68674 0.5 0.86523 0.15194 0.088045 0.32439 0.13452 0.5 0.13477v1h5 1v-1h-1v-4h2v-2h2v-3h3v-2c0-1.1046-0.89543-2-2-2h-7z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m6 1c-1.1046 0-2 0.89543-2 2v7h-2-1v1 2c0 1.1046 0.89543 2 2 2s2-0.89543 2-2v-10c0-0.55228 0.44772-1 1-1s1 0.44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-0.89543-2-2-2zm-4 10h2v2c0 0.55228-0.44772 1-1 1s-1-0.44772-1-1v-2z" fill="#000000"/>
-<circle cx="3" cy="1048.4" rx="1" ry="1" fill="#4f4f4f"/>
-<path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#00f010" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_script_remove.svg b/editor/icons/dark/icon_script_remove.svg
deleted file mode 100644
index d619a3f94f..0000000000
--- a/editor/icons/dark/icon_script_remove.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 1v1c-0.55228 0-1 0.44772-1 1v10h-1v-2h-2v2c2.826e-4 0.35698 0.19084 0.68674 0.5 0.86523 0.15194 0.088045 0.32439 0.13452 0.5 0.13477v1h5.6348l-1.584-1.584 1.4141-1.4141-1.4141-1.416 3.5352-3.5352 1.4141 1.4141v-0.46484-3h3v-2c0-1.1046-0.89543-2-2-2h-7z" fill="#4f4f4f"/>
-<path transform="translate(0 1036.4)" d="m6 1c-1.1046 0-2 0.89543-2 2v7h-2-1v1 2c0 1.1046 0.89543 2 2 2s2-0.89543 2-2v-10c0-0.55228 0.44772-1 1-1s1 0.44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-0.89543-2-2-2zm-4 10h2v2c0 0.55228-0.44772 1-1 1s-1-0.44772-1-1v-2z" fill="#000000"/>
-<circle cx="3" cy="1048.4" rx="1" ry="1" fill="#4f4f4f"/>
-<path d="m13.414 1048.4 1.4142-1.4142-1.4142-1.4142l-1.4142 1.4142-1.4142-1.4142-1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142-1.4142z" fill="#ff4040" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_scroll_bar.svg b/editor/icons/dark/icon_scroll_bar.svg
deleted file mode 100644
index 45a37b576a..0000000000
--- a/editor/icons/dark/icon_scroll_bar.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 3c-1.1046 0-2 0.89543-2 2v6c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-6c0-1.1046-0.89543-2-2-2zm0 2h10v6h-10z" fill="#29d739"/>
-<rect x="4" y="1042.4" width="4" height="4" fill="none"/>
-<rect x="4" y="1042.4" width="4" height="4" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_scroll_container.svg b/editor/icons/dark/icon_scroll_container.svg
deleted file mode 100644
index 3c4d3ce47d..0000000000
--- a/editor/icons/dark/icon_scroll_container.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z"/>
-<path d="m10 1042.4v4l2-2z"/>
-<path d="m6 1042.4v4l-2-2z"/>
-<path d="m6 1042.4h4l-2-2z"/>
-<path d="m6 1046.4h4l-2 2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_search.svg b/editor/icons/dark/icon_search.svg
deleted file mode 100644
index 13ebcd817c..0000000000
--- a/editor/icons/dark/icon_search.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path d="m6 1037.4a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5 -5 5 5 0 0 0 -5 -5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3 -3 3 3 0 0 1 3 -3z"/>
-<rect transform="matrix(.70711 -.70711 .70711 .70711 0 0)" x="-733.82" y="745.3" width="2" height="7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_segment_shape_2d.svg b/editor/icons/dark/icon_segment_shape_2d.svg
deleted file mode 100644
index beb1dd3d3f..0000000000
--- a/editor/icons/dark/icon_segment_shape_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1050.4 12-12" color="#000000" fill="none" stroke="#68b6ff" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_shader.svg b/editor/icons/dark/icon_shader.svg
deleted file mode 100644
index 46fd13c5b3..0000000000
--- a/editor/icons/dark/icon_shader.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v1h2 6 3l-2-2h-8z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m1 3v2h2v-2h-2zm8 0v2h5l-2-2h-3z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m1 5v2h2v-2h-2zm8 0v1c0 0.554 0.44599 1 1 1h3 2v-1l-1-1h-5z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1 7v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1 9v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m1 13v1c5.52e-5 0.5523 0.44774 0.9999 1 1h12c0.55226-1e-4 0.99994-0.4477 1-1v-1h-2-10-2z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m1 11v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_short_cut.svg b/editor/icons/dark/icon_short_cut.svg
deleted file mode 100644
index 204b53f9db..0000000000
--- a/editor/icons/dark/icon_short_cut.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m4 2c-0.55228 0-1 0.4477-1 1v9.084c4.015e-4 0.506 0.448 0.91602 1 0.91602h8c0.552 0 0.9996-0.41002 1-0.91602v-9.084c0-0.5523-0.44772-1-1-1h-8zm-3 2v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-1v9a0.99998 0.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1 -1v-9h-1zm6 0h3l-1 3h2l-4 4 1-3h-2l1-4z" fill="#4f4f4f"/>
-<rect x="27" y="1038.4" width="7" height="14" fill="#000000"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_signal.svg b/editor/icons/dark/icon_signal.svg
deleted file mode 100644
index c764bdc1a7..0000000000
--- a/editor/icons/dark/icon_signal.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff4040">
-<rect x="5" y="1043.4" width="6" height="2"/>
-<path transform="matrix(0 1.281 -.9245 0 -948.3 1038)" d="m8.1225-1036.6h-3.1225-3.1225l1.5612-2.7042 1.5612-2.7041 1.5612 2.7041z"/>
-<rect x="1" y="1039.4" width="2" height="10"/>
-<rect x="3" y="1047.4" width="4" height="2"/>
-<rect x="3" y="1039.4" width="4" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_skeleton.svg b/editor/icons/dark/icon_skeleton.svg
deleted file mode 100644
index cfd23a5e51..0000000000
--- a/editor/icons/dark/icon_skeleton.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 3 3.8691v-0.86914h1v1h1v-1h1 1v1h1v-1h1v0.86719a4 4 0 0 0 3 -3.8672 4 4 0 0 0 -4 -4h-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-4 2h2v1h-2v-1z"/>
-<path transform="translate(0 1036.4)" d="m4 9v4h1v-4h-1zm7 0v4h1v-4h-1zm-5 3v1 2h4v-2-1h-1v1h-2v-1h-1z"/>
-<path d="m8 1049.4a2 2 0 0 1 -1 1.732 2 2 0 0 1 -2 0 2 2 0 0 1 -1 -1.732h2z"/>
-<path d="m12 1049.4a2 2 0 0 1 -1 1.732 2 2 0 0 1 -2 0 2 2 0 0 1 -1 -1.732h2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_slider_joint.svg b/editor/icons/dark/icon_slider_joint.svg
deleted file mode 100644
index c46855342e..0000000000
--- a/editor/icons/dark/icon_slider_joint.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m3 1051.4h5l-1-4z" fill="#ff5f5f" fill-opacity=".99608"/>
-<path d="m6 1048.4 9-9v3l-8 8z" fill="#fb9b9b"/>
-<path d="m10 1040.4-9 9v-3l8-8z" fill="#fb9b9b"/>
-<path d="m13 1037.4h-5l1 4z" fill="#ff5f5f" fill-opacity=".99608"/>
-<path d="m10 1038.4h-5" fill="none" stroke="#fb9b9b" stroke-linecap="round" stroke-width="2"/>
-<path d="m11 1050.4h-5" fill="none" stroke="#fb9b9b" stroke-linecap="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_slot.svg b/editor/icons/dark/icon_slot.svg
deleted file mode 100644
index 9e8a5038e3..0000000000
--- a/editor/icons/dark/icon_slot.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#00f010">
-<rect x="1" y="1043.4" width="6" height="2"/>
-<path transform="matrix(0 1.281 -.9245 0 -952.3 1038)" d="m8.1225-1036.6h-3.1225-3.1225l1.5612-2.7042 1.5612-2.7041 1.5612 2.7041z"/>
-<path d="m15 1039.4v10h-2-4v-2h4v-6h-4v-2h4 2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_snap.svg b/editor/icons/dark/icon_snap.svg
deleted file mode 100644
index 7c3e75f7cd..0000000000
--- a/editor/icons/dark/icon_snap.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m3 1036.4v3h-3v2h3v4h-3v2h3v3h2v-3-2-4h4 2 3v-2h-3v-3h-2v3h-4v-3h-2z" fill="#f3f3f3"/>
-<path d="m11 1043.4a4 4 0 0 0 -4 4h2a2 2 0 0 1 2 -2 2 2 0 0 1 2 2h2a4 4 0 0 0 -4 -4z" fill="#ff4040"/>
-<rect x="7" y="1047.4" width="2" height="2" fill="#ff4040"/>
-<rect x="13" y="1047.4" width="2" height="2" fill="#ff4040"/>
-<rect x="7" y="1049.4" width="2" height="2" fill="#000000"/>
-<rect x="13" y="1049.4" width="2" height="2" fil#000000fff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sort.svg b/editor/icons/dark/icon_sort.svg
deleted file mode 100644
index 87bab3cad7..0000000000
--- a/editor/icons/dark/icon_sort.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m9 1v2h6v-2h-6zm-5.0156 0.0019531a1.0001 1.0001 0 0 0 -0.69141 0.29102l-2 2a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l0.29297-0.29297v7.1719l-0.29297-0.29297a1 1 0 0 0 -0.7207 -0.29102 1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l2 2a1.0001 1.0001 0 0 0 1.4141 0l2-2a1 1 0 0 0 0 -1.4141 1 1 0 0 0 -1.4141 0l-0.29297 0.29297v-7.1719l0.29297 0.29297a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-2-2a1.0001 1.0001 0 0 0 -0.72266 -0.29102zm5.0156 5.998v2h4v-2h-4zm0 6v2h2v-2h-2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#4f4f4f" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sound_room_params.svg b/editor/icons/dark/icon_sound_room_params.svg
deleted file mode 100644
index f9c6624284..0000000000
--- a/editor/icons/dark/icon_sound_room_params.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path d="m8 1037.4-4 5h-3v4h3l4 5v-14z"/>
-<path d="m13 1039.4v10h1v-10h-1z"/>
-<path d="m10 1039.4v10h1v-10h-1z"/>
-<rect x="9" y="1041.4" width="3" height="1"/>
-<rect x="12" y="1046.4" width="3" height="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_spatial.svg b/editor/icons/dark/icon_spatial.svg
deleted file mode 100644
index b89620314b..0000000000
--- a/editor/icons/dark/icon_spatial.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6 -6 6 6 0 0 0 -6 -6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_spatial_material.svg b/editor/icons/dark/icon_spatial_material.svg
deleted file mode 100644
index 57b6fd360d..0000000000
--- a/editor/icons/dark/icon_spatial_material.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-3.7891 1.8945h8.4727l-3.7891-1.8945a1.0001 1.0001 0 0 0 -0.48438 -0.10352z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m3.7637 3l-2.2109 1.1055a1.0001 1.0001 0 0 0 -0.55273 0.89453h3.2363l3.7637-1.8809 3.7637 1.8809h3.2363a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-2.2109-1.1055h-8.4727z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m1 5v2h2v-0.38086l0.76172 0.38086h8.4766l0.76172-0.38086v0.38086h2v-2h-3.2363l-3.7637 1.8828-3.7637-1.8828h-3.2363z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1 7v2h2v-2h-2zm2.7617 0l3.2383 1.6191v0.38086h2v-0.38086l3.2383-1.6191h-8.4766zm9.2383 0v2h2v-2h-2z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1 9v2h3.2344l-1.2344-0.61719v-1.3828h-2zm6 0v2h2v-2h-2zm6 0v1.3828l-1.2344 0.61719h3.2344v-2h-2z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m3.7637 13l3.7891 1.8945a1.0001 1.0001 0 0 0 0.48438 0.10547 1.0001 1.0001 0 0 0 0.41016 -0.10547l3.7891-1.8945h-8.4727z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m1 11a1.0001 1.0001 0 0 0 0.55273 0.89453l2.2109 1.1055h8.4727l2.2109-1.1055a1.0001 1.0001 0 0 0 0.55273 -0.89453h-3.2344l-2.7656 1.3828v-1.3828h-2v1.3828l-2.7656-1.3828h-3.2344z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_spatial_sample_player.svg b/editor/icons/dark/icon_spatial_sample_player.svg
deleted file mode 100644
index e0925fdd7a..0000000000
--- a/editor/icons/dark/icon_spatial_sample_player.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1l-4 5h-3v4h3l4 5v-14zm5 2v10h1v-10h-1zm-3 3v5h1v-5h-1z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_spatial_stream_player.svg b/editor/icons/dark/icon_spatial_stream_player.svg
deleted file mode 100644
index 60c5749bb8..0000000000
--- a/editor/icons/dark/icon_spatial_stream_player.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 2c-0.55228 0-1 0.44772-1 1v1 7h-2c-0.55228 0-1 0.44772-1 1v2c0 0.55228 0.44772 1 1 1h2 1c0.55228 0 1-0.44772 1-1v-3-7h6v5h-2c-0.55228 0-1 0.44772-1 1v2c0 0.55228 0.44772 1 1 1h3c0.55228 0 1-0.44772 1-1v-3-6c0-0.55228-0.44772-1-1-1h-7z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sphere_mesh.svg b/editor/icons/dark/icon_sphere_mesh.svg
deleted file mode 100644
index 317741595e..0000000000
--- a/editor/icons/dark/icon_sphere_mesh.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7 3.8541 0 7-3.1458 7-7 0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-0.071342-2.6061-0.29819-3.9434-0.69141 0.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549 0.41253 3.637 2.0767 3.9414 4.1699-1.3046 0.36677-2.6158 0.60259-3.9414 0.6875v-4.8574zm3.7852 6.2812c-0.50864 1.7788-1.9499 3.1531-3.7852 3.5215v-2.9512c1.2792-0.072301 2.5419-0.26704 3.7852-0.57031zm-9.5645 0.017578c1.2733 0.31892 2.5337 0.50215 3.7793 0.5625v2.9414c-1.8291-0.36719-3.266-1.7339-3.7793-3.5039z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fea900" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sphere_shape.svg b/editor/icons/dark/icon_sphere_shape.svg
deleted file mode 100644
index f2995ae96a..0000000000
--- a/editor/icons/dark/icon_sphere_shape.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<circle cx="8" cy="1044.4" r="7" fill="#68b6ff"/>
-<circle cx="6" cy="1041.4" r="2" fill="#a2d2ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_spin_box.svg b/editor/icons/dark/icon_spin_box.svg
deleted file mode 100644
index 2d0376e280..0000000000
--- a/editor/icons/dark/icon_spin_box.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 3c-1.1046 0-2 0.89543-2 2v6c0 1.1046 0.89543 2 2 2h7v-2h-7v-6h7v-2z"/>
-<rect x="8" y="1041.4" width="2" height="6"/>
-<path d="m11 1043.4h4l-2-3z" fill-rule="evenodd"/>
-<path d="m11 1045.4h4l-2 3z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_spot_light.svg b/editor/icons/dark/icon_spot_light.svg
deleted file mode 100644
index 9e333acce0..0000000000
--- a/editor/icons/dark/icon_spot_light.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 1a1 1 0 0 0 -1 1v3.6934c-1.7861 0.86608-3 2.4605-3 4.3066h4a2 2 0 0 0 2 2 2 2 0 0 0 2 -2h4c0-1.8462-1.2139-3.4406-3-4.3066v-3.6934a1 1 0 0 0 -1 -1h-4zm-1.0977 9.6348l-1.7324 1 1 1.7305 1.7324-1-1-1.7305zm6.1953 0l-1 1.7305 1.7324 1 1-1.7305-1.7324-1zm-4.0977 2.3652v2h2v-2h-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sprite.svg b/editor/icons/dark/icon_sprite.svg
deleted file mode 100644
index 7c7f7dde76..0000000000
--- a/editor/icons/dark/icon_sprite.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-4 5a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm8 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-7 3h6a3 3 0 0 1 -1.5 2.5977 3 3 0 0 1 -3 0 3 3 0 0 1 -1.5 -2.5977z" fill="#6d90ff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sprite_3d.svg b/editor/icons/dark/icon_sprite_3d.svg
deleted file mode 100644
index 9f6d4f9fe5..0000000000
--- a/editor/icons/dark/icon_sprite_3d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-4 5a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm8 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-7 3h6a3 3 0 0 1 -1.5 2.5977 3 3 0 0 1 -3 0 3 3 0 0 1 -1.5 -2.5977z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_sprite_frames.svg b/editor/icons/dark/icon_sprite_frames.svg
deleted file mode 100644
index e4f85236b4..0000000000
--- a/editor/icons/dark/icon_sprite_frames.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="10" y="1046.4" width="2" height="2"/>
-<rect x="13" y="1046.4" width="2" height="2"/>
-<rect x="10" y="1049.4" width="2" height="2"/>
-<rect x="13" y="1049.4" width="2" height="2"/>
-<path transform="translate(0 1036.4)" d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5 -5 5 5 0 0 0 -5 -5zm-3 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-1.0039 2.4922a0.50005 0.50005 0 0 1 0.35742 0.86133c-0.61785 0.6179-1.4924 0.89648-2.3535 0.89648s-1.7357-0.27858-2.3535-0.89648a0.50005 0.50005 0 0 1 0.34766 -0.85742 0.50005 0.50005 0 0 1 0.35938 0.15039c0.38215 0.3822 1.0076 0.60352 1.6465 0.60352s1.2643-0.22132 1.6465-0.60352a0.50005 0.50005 0 0 1 0.34961 -0.1543z"/>
-<rect x="13" y="1043.4" width="2" height="2"/>
-<rect x="7" y="1049.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_static_body.svg b/editor/icons/dark/icon_static_body.svg
deleted file mode 100644
index 04944fd5c8..0000000000
--- a/editor/icons/dark/icon_static_body.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -1.4141 0.58594 2 2 0 0 0 -0.58594 1.4141v10a2 2 0 0 0 0.58594 1.4141 2 2 0 0 0 1.4141 0.58594h10a2 2 0 0 0 2 -2v-10a2 2 0 0 0 -2 -2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1 -1v-10a1 1 0 0 1 1 -1zm0 1v2h2v-2h-2zm8 0v2h2v-2h-2zm-8 8v2h2v-2h-2zm8 0v2h2v-2h-2z" fill="#ff5f5f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_static_body_2d.svg b/editor/icons/dark/icon_static_body_2d.svg
deleted file mode 100644
index 36a63281d2..0000000000
--- a/editor/icons/dark/icon_static_body_2d.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -1.4141 0.58594 2 2 0 0 0 -0.58594 1.4141v10a2 2 0 0 0 0.58594 1.4141 2 2 0 0 0 1.4141 0.58594h10a2 2 0 0 0 2 -2v-10a2 2 0 0 0 -2 -2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1 -1v-10a1 1 0 0 1 1 -1zm0 1v2h2v-2h-2zm8 0v2h2v-2h-2zm-8 8v2h2v-2h-2zm8 0v2h2v-2h-2z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_stop.svg b/editor/icons/dark/icon_stop.svg
deleted file mode 100644
index 1b856b5153..0000000000
--- a/editor/icons/dark/icon_stop.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m4 1048.4v-8h8v8z" fill="#4f4f4f" fill-rule="evenodd" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_stream_player.svg b/editor/icons/dark/icon_stream_player.svg
deleted file mode 100644
index b9592a6cd8..0000000000
--- a/editor/icons/dark/icon_stream_player.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 2c-0.55228 0-1 0.44772-1 1v1 7h-2c-0.55228 0-1 0.44772-1 1v2c0 0.55228 0.44772 1 1 1h2 1c0.55228 0 1-0.44772 1-1v-3-7h6v5h-2c-0.55228 0-1 0.44772-1 1v2c0 0.55228 0.44772 1 1 1h3c0.55228 0 1-0.44772 1-1v-3-6c0-0.55228-0.44772-1-1-1h-7z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_stream_texture.svg b/editor/icons/dark/icon_stream_texture.svg
deleted file mode 100644
index 1a78b5b41a..0000000000
--- a/editor/icons/dark/icon_stream_texture.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h6v-2h2v-2h-2-5v-8h5v-2h-6zm6 2v2h2v-2h-2zm2 0h2v-2h-2v2zm2 0v2h2v-2h-2zm0 2h-2v2h2v-2zm0 2v2h2v-2h-2zm0 2h-2v2h2v-2zm0 2v2h2v-2h-2zm0 2h-2v2h2v-2zm-2-4v-2h-2v-1h-1v1h-1v1h-1v1h-1v1h2 2v-1h2z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_string.svg b/editor/icons/dark/icon_string.svg
deleted file mode 100644
index 9bb7518995..0000000000
--- a/editor/icons/dark/icon_string.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 1v2h2v10h-2v2h2a1 1 0 0 0 1 -1 1 1 0 0 0 1 1h2v-2h-2v-10h2v-2h-2a1 1 0 0 0 -1 1 1 1 0 0 0 -1 -1h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_style_box_empty.svg b/editor/icons/dark/icon_style_box_empty.svg
deleted file mode 100644
index c3791985cf..0000000000
--- a/editor/icons/dark/icon_style_box_empty.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v1h2v-2h-1zm3 0v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h2v-1c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-1z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m1 5v2h2v-2h-2zm12 0v0.23242c0.31584 0.1783 0.57817 0.43795 0.75977 0.75195 0.19142 0.33153 0.43699 0.67036 0.69922 1.0156h0.54102v-2h-2z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m12 7c-0.43047 0.7456-0.94451 1.3867-1.4355 2h2.8711c-0.49104-0.6133-1.0051-1.2544-1.4355-2zm2.459 0c0.17438 0.2296 0.352 0.46082 0.54102 0.69922v-0.69922h-0.54102z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1 9v2h2v-2h-2zm9.5645 0c-0.55248 0.69003-1.0583 1.3421-1.334 2h5.5391c-0.2757-0.65786-0.78151-1.31-1.334-2h-2.8711z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m1 13v1c5.52e-5 0.5523 0.44774 0.9999 1 1h1v-2h-2zm4 0v2h2v-2h-2zm4.1836 0c0.41312 1.1628 1.5119 2 2.8164 2s2.4033-0.83718 2.8164-2h-5.6328z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m9.2305 11c-0.13656 0.32585-0.23047 0.65576-0.23047 1 0 0.35235 0.07201 0.68593 0.18359 1h5.6328c0.11158-0.31407 0.18359-0.64765 0.18359-1 0-0.34424-0.093909-0.67415-0.23047-1h-5.5391z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_style_box_flat.svg b/editor/icons/dark/icon_style_box_flat.svg
deleted file mode 100644
index f0270c7cc5..0000000000
--- a/editor/icons/dark/icon_style_box_flat.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v1h14v-1c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-12z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m1 3v2h14v-2h-14z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m1 5v2h8.582c0.25686-0.33847 0.49465-0.66934 0.68555-1 0.33885-0.5859 0.95103-0.96109 1.627-0.99609 0.7512-0.04 1.4613 0.34489 1.8379 0.99609 0.18899 0.32737 0.42831 0.66049 0.68555 1h0.58203v-2h-14z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1 7v2h7.0547c0.14116-0.20345 0.28508-0.40233 0.42383-0.58398 0.38601-0.5053 0.76348-0.96794 1.1035-1.416h-8.582zm11 0c-0.43047 0.7456-0.94451 1.3867-1.4355 2h2.8711c-0.49104-0.6133-1.0051-1.2544-1.4355-2zm2.418 0c0.18626 0.24583 0.37928 0.49419 0.58203 0.75v-0.75h-0.58203z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1 9v2h6.1172c0.17955-0.78395 0.54577-1.4354 0.9375-2h-7.0547zm9.5645 0c-0.55248 0.69003-1.0583 1.3421-1.334 2h5.5391c-0.2757-0.65786-0.78151-1.31-1.334-2h-2.8711z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m1 13v1c5.52e-5 0.5523 0.44774 0.9999 1 1h6.0371c-0.44511-0.58388-0.76161-1.2639-0.91992-2h-6.1172zm8.1836 0c0.41312 1.1628 1.5119 2 2.8164 2s2.4033-0.83718 2.8164-2h-5.6328z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m1 11v2h6.1172c-0.06966-0.3239-0.11719-0.65596-0.11719-1 0-0.35655 0.045474-0.68688 0.11719-1h-6.1172zm8.2305 0c-0.13656 0.32585-0.23047 0.65576-0.23047 1 0 0.35235 0.07201 0.68593 0.18359 1h5.6328c0.11158-0.31407 0.18359-0.64765 0.18359-1 0-0.34424-0.093909-0.67415-0.23047-1h-5.5391z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_style_box_texture.svg b/editor/icons/dark/icon_style_box_texture.svg
deleted file mode 100644
index 36fdd7f66b..0000000000
--- a/editor/icons/dark/icon_style_box_texture.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v1h2 10 2v-1a1.0001 1.0001 0 0 0 -1 -1h-12z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m1 3v2h2v-2h-2zm12 0v2h2v-2h-2zm-4 1v1h1v-1h-1z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m1 5v2h2v-2h-2zm7 0v1h-2v1h3.543c0.26215-0.34438 0.50373-0.68039 0.69727-1.0156a2.0315 2.0315 0 0 1 0.75977 -0.75195v-0.23242h-1-1-1zm5 0v0.23242a2.0315 2.0315 0 0 1 0.75977 0.75195c0.19142 0.33153 0.43699 0.67033 0.69922 1.0156h0.54102v-2h-2z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1 7v2h2v-2h-2zm4 0v1h-1v1h4.0156c0.14585-0.2113 0.29419-0.41592 0.4375-0.60352 0.38121-0.49904 0.75394-0.95521 1.0898-1.3965h-3.543-1zm7 0c-0.43047 0.7456-0.94451 1.3867-1.4355 2h2.8711c-0.49104-0.6133-1.0051-1.2544-1.4355-2zm2.459 0c0.17438 0.22962 0.352 0.46082 0.54102 0.69922v-0.69922h-0.54102z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1 9v2h2v-2h-2zm9.5645 0c-0.55248 0.69003-1.0583 1.3421-1.334 2h5.5391c-0.2757-0.65786-0.78151-1.31-1.334-2h-2.8711z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m1 13v1a1.0001 1.0001 0 0 0 1 1h5.998c-0.4429-0.5864-0.77294-1.2592-0.92578-2h-4.0723-2zm8.1836 0c0.41312 1.1628 1.5119 2 2.8164 2s2.4033-0.83718 2.8164-2h-5.6328z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m1 11v2h2v-2h-2zm8.2305 0c-0.13656 0.32585-0.23047 0.65576-0.23047 1 0 0.35235 0.07201 0.68593 0.18359 1h5.6328c0.11158-0.31407 0.18359-0.64765 0.18359-1 0-0.34424-0.093909-0.67415-0.23047-1h-5.5391z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tab_container.svg b/editor/icons/dark/icon_tab_container.svg
deleted file mode 100644
index d47e1522c6..0000000000
--- a/editor/icons/dark/icon_tab_container.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h5v2 2h5v6h-10v-10zm7 0h3v2h-3v-2z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tabs.svg b/editor/icons/dark/icon_tabs.svg
deleted file mode 100644
index b8bfdefa90..0000000000
--- a/editor/icons/dark/icon_tabs.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 4c-1.108 0-1.8178 0.9071-2 2l-1 6h-1v2h4 6 4v-2h-2l-1-6c-0.18216-1.0929-0.89199-2-2-2h-5z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_test_cube.svg b/editor/icons/dark/icon_test_cube.svg
deleted file mode 100644
index e6d3ac88f2..0000000000
--- a/editor/icons/dark/icon_test_cube.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="translate(0 1.1802e-5)" stroke="#ff5f5f" stroke-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-6 3a1.0001 1.0001 0 0 0 -0.55273 0.89453v6a1.0001 1.0001 0 0 0 0.55273 0.89453l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.89453v-6a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-6-3a1.0001 1.0001 0 0 0 -0.48438 -0.10352zm0.037109 2.1172l3.7637 1.8809-3.7637 1.8828-3.7637-1.8828 3.7637-1.8809zm-5 3.5l4 2v3.7637l-4-2v-3.7637zm10 0v3.7637l-4 2v-3.7637l4-2z" color="#000000" color-rendering="auto" fill="#ff5f5f" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" stroke="none" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_text_edit.svg b/editor/icons/dark/icon_text_edit.svg
deleted file mode 100644
index 7c449830b1..0000000000
--- a/editor/icons/dark/icon_text_edit.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.8954-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v10h-10v-10zm1 1v4h1v-4h-1z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_texture_button.svg b/editor/icons/dark/icon_texture_button.svg
deleted file mode 100644
index 1de3da6cda..0000000000
--- a/editor/icons/dark/icon_texture_button.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 3v8h14v-8h-1-12-1zm8 2h1v1h1v2h1v2h-2-2-2-2v-1h1v-1h1v-1h2v-1h1v-1z" fill="#29d739"/>
-<rect transform="scale(1,-1)" x="1" y="-1049.4" width="14" height="2.0001" fill="#29d739"/>
-<rect transform="scale(1,-1)" x="1" y="-1049.4" width="14" height="2.0001" fill-opacity=".078431"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_texture_progress.svg b/editor/icons/dark/icon_texture_progress.svg
deleted file mode 100644
index 17aae8239a..0000000000
--- a/editor/icons/dark/icon_texture_progress.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 3c-1.1046 0-2 0.89543-2 2v6c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-6c0-1.1046-0.89543-2-2-2zm0 2h10v6h-10z"/>
-<rect x="4" y="1042.4" width="1" height="2"/>
-<rect x="6" y="1043.4" width="1" height="3"/>
-<rect x="8" y="1042.4" width="1" height="4"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_texture_rect.svg b/editor/icons/dark/icon_texture_rect.svg
deleted file mode 100644
index 540c237f28..0000000000
--- a/editor/icons/dark/icon_texture_rect.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="2" y="1038.4" width="12" height="12" fill="none" stroke="#29d739" stroke-linecap="round" stroke-width="2"/>
-<path d="m9 1042.4v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1h-1z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_theme.svg b/editor/icons/dark/icon_theme.svg
deleted file mode 100644
index 4d5c017f14..0000000000
--- a/editor/icons/dark/icon_theme.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1l-0.5 2h3l-0.5-2h-2zm-3.2422 1.3438l-0.65625 0.65625h1.75l-1.0938-0.65625zm8.4844 0l-1.0957 0.65625h1.752l-0.65625-0.65625z" fill="#ff2929"/>
-<path transform="translate(0 1036.4)" d="m3.1016 3l-0.75781 0.75781 0.74414 1.2422h9.8242l0.74414-1.2422-0.75781-0.75781h-1.752l-0.89844 0.53906a5 5 0 0 0 -0.68555 -0.28516l-0.0625-0.25391h-3l-0.064453 0.25781a5 5 0 0 0 -0.68945 0.2793l-0.89453-0.53711h-1.75z" fill="#ffe337"/>
-<path transform="translate(0 1036.4)" d="m3.0879 5l0.45117 0.75195a5 5 0 0 0 -0.28516 0.68555l-2.2539 0.5625h5.2695a2 2 0 0 1 1.7305 -1 2 2 0 0 1 1.7285 1h5.2715l-2.2578-0.56445a5 5 0 0 0 -0.2793 -0.6875l0.44922-0.74805h-9.8242z" fill="#74ff34"/>
-<path transform="translate(0 1036.4)" d="m1 7v2h5.2715a2 2 0 0 1 -0.27148 -1 2 2 0 0 1 0.26953 -1h-5.2695zm8.7285 0a2 2 0 0 1 0.27148 1 2 2 0 0 1 -0.26953 1h5.2695v-2h-5.2715z" fill="#2cff98"/>
-<path transform="translate(0 1036.4)" d="m1 9l2.2578 0.56445a5 5 0 0 0 0.2793 0.6875l-0.44922 0.74805h9.8242l-0.45117-0.75195a5 5 0 0 0 0.28516 -0.68555l2.2539-0.5625h-5.2695a2 2 0 0 1 -1.7305 1 2 2 0 0 1 -1.7285 -1h-5.2715z" fill="#22ccff"/>
-<path transform="translate(0 1036.4)" d="m3.1016 13l0.65625 0.65625 1.0957-0.65625h-1.752zm3.3984 0l0.5 2h2l0.5-2h-3zm4.6484 0l1.0938 0.65625 0.65625-0.65625h-1.75z" fill="#ff2781"/>
-<path transform="translate(0 1036.4)" d="m3.0879 11l-0.74414 1.2422 0.75781 0.75781h1.752l0.89844-0.53906a5 5 0 0 0 0.68555 0.28516l0.0625 0.25391h3l0.064453-0.25781a5 5 0 0 0 0.6875 -0.2793l0.89648 0.53711h1.75l0.75781-0.75781-0.74414-1.2422h-9.8242z" fill="#702aff"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_thumbnail_wait.svg b/editor/icons/dark/icon_thumbnail_wait.svg
deleted file mode 100644
index 833e6f7f69..0000000000
--- a/editor/icons/dark/icon_thumbnail_wait.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -988.36)">
-<path transform="translate(0 988.36)" d="m8 0c-4.432 0-8 3.568-8 8v48c0 4.432 3.568 8 8 8h48c4.432 0 8-3.568 8-8v-48c0-4.432-3.568-8-8-8h-48zm0 2h48c3.324 0 6 2.676 6 6v48c0 3.324-2.676 6-6 6h-48c-3.324 0-6-2.676-6-6v-48c0-3.324 2.676-6 6-6zm-0.013672 5.002a1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l8 8a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-8-8a1 1 0 0 0 -0.7207 -0.29102zm48 0a1 1 0 0 0 -0.69336 0.29102l-8 8a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l8-8a1 1 0 0 0 0 -1.4141 1 1 0 0 0 -0.7207 -0.29102zm-33.986 10.998a2.0002 2.0002 0 0 0 -0.37891 0.039062c-0.005702 0.001087-0.011894 8.19e-4 -0.017578 0.001954-0.01402 0.002798-0.027106 0.006677-0.041016 0.009765a2.0002 2.0002 0 0 0 -0.30859 0.095703c-0.024592 0.009869-0.048174 0.020446-0.072265 0.03125a2.0002 2.0002 0 0 0 -0.24609 0.13281c-0.021344 0.013452-0.043669 0.024834-0.064453 0.039062-0.008816 0.006036-0.016678 0.013359-0.025391 0.019532a2.0002 2.0002 0 0 0 -0.21484 0.17578c-0.0215 0.020231-0.04387 0.039386-0.064453 0.060547a2.0002 2.0002 0 0 0 -0.001953 0.001953 2.0002 2.0002 0 0 0 -0.18555 0.22461c-0.017788 0.024669-0.036063 0.048717-0.052734 0.074219a2.0002 2.0002 0 0 0 -0.14258 0.26562c-0.013621 0.029909-0.026892 0.059158-0.039063 0.089844a2.0002 2.0002 0 0 0 -0.09375 0.30078c-0.004203 0.018931-0.008053 0.037509-0.011719 0.056641a2.0002 2.0002 0 0 0 -0.039062 0.38086c0 3 1.9339 5.2454 3.7461 7.3164 1.5217 1.7392 2.8322 3.2888 3.75 4.6836-0.91778 1.3948-2.2283 2.9444-3.75 4.6836-1.8122 2.071-3.7461 4.3164-3.7461 7.3164a2.0002 2.0002 0 0 0 0.041016 0.4043 2.0002 2.0002 0 0 0 0.10547 0.3418c0.008774 0.021862 0.017831 0.042985 0.027344 0.064453a2.0002 2.0002 0 0 0 0.14648 0.27344c0.010017 0.015513 0.018867 0.031664 0.029297 0.046875l0.001953 0.001953a2.0002 2.0002 0 0 0 0.19336 0.23633c0.020231 0.0215 0.039386 0.04387 0.060547 0.064453a2.0002 2.0002 0 0 0 0.001953 0.001953 2.0002 2.0002 0 0 0 0.23438 0.19336c0.021387 0.01522 0.042447 0.030536 0.064453 0.044922a2.0002 2.0002 0 0 0 0.27734 0.15039c0.019743 0.008822 0.038513 0.019147 0.058594 0.027343a2.0002 2.0002 0 0 0 0.33789 0.10352c0.005331 0.001131 0.010278 0.002818 0.015625 0.003906a2.0002 2.0002 0 0 0 0.009766 0 2.0002 2.0002 0 0 0 0.39453 0.041016h20a2.0002 2.0002 0 0 0 0.4043 -0.041016 2.0002 2.0002 0 0 0 0.375 -0.11523 2.0002 2.0002 0 0 0 0.29297 -0.1582c0.018831-0.011984 0.038248-0.022566 0.05664-0.035156a2.0002 2.0002 0 0 0 0.021485 -0.015625 2.0002 2.0002 0 0 0 0.23633 -0.19531c0.013296-0.012808 0.028079-0.023939 0.041015-0.037109a2.0002 2.0002 0 0 0 0.20508 -0.25c0.012127-0.017168 0.025518-0.033217 0.03711-0.050782a2.0002 2.0002 0 0 0 0.15234 -0.28125c0.01106-0.024605 0.021165-0.049089 0.03125-0.074218a2.0002 2.0002 0 0 0 0.097656 -0.31445c0.003563-0.016291 0.0066-0.03239 0.009766-0.048829a2.0002 2.0002 0 0 0 0.039062 -0.38281c0-3-1.9339-5.2454-3.7461-7.3164-1.5217-1.7392-2.8322-3.2888-3.75-4.6836 0.91778-1.3948 2.2283-2.9444 3.75-4.6836 1.8122-2.071 3.7461-4.3164 3.7461-7.3164a2.0002 2.0002 0 0 0 -0.041016 -0.4043v-0.001953a2.0002 2.0002 0 0 0 -0.10156 -0.32617c-0.011965-0.03044-0.023719-0.060163-0.03711-0.089844a2.0002 2.0002 0 0 0 -0.13476 -0.25c-0.011984-0.018831-0.022566-0.038248-0.035156-0.05664a2.0002 2.0002 0 0 0 -0.023438 -0.03125 2.0002 2.0002 0 0 0 -0.1582 -0.19336c-0.025026-0.027154-0.049686-0.054353-0.076172-0.080078a2.0002 2.0002 0 0 0 -0.027344 -0.02539 2.0002 2.0002 0 0 0 -0.18945 -0.1543c-0.031037-0.022641-0.061384-0.04555-0.09375-0.066407l-0.001953-0.001953a2.0002 2.0002 0 0 0 -0.24219 -0.13086c-0.031326-0.014467-0.061564-0.030098-0.09375-0.042969a2.0002 2.0002 0 0 0 -0.29883 -0.091797c-0.021554-0.004877-0.042636-0.009492-0.064453-0.013672a2.0002 2.0002 0 0 0 -0.38086 -0.039062h-20zm3.1758 4h13.648c-0.4756 0.8814-0.611 1.5782-1.5781 2.6836-1.6878 1.929-3.7966 3.9449-5.0352 6.4219a2.0002 2.0002 0 0 0 -0.20898 0.89453h-0.003906a2.0002 2.0002 0 0 0 -0.20898 -0.89453c-1.2385-2.477-3.3473-4.4929-5.0352-6.4219-0.96713-1.1054-1.1025-1.8022-1.5781-2.6836zm-9.1895 25.002a1 1 0 0 0 -0.69336 0.29102l-8 8a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l8-8a1 1 0 0 0 0 -1.4141 1 1 0 0 0 -0.7207 -0.29102zm32 0a1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l8 8a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-8-8a1 1 0 0 0 -0.7207 -0.29102z" fill="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tile_map.svg b/editor/icons/dark/icon_tile_map.svg
deleted file mode 100644
index 9de80deff8..0000000000
--- a/editor/icons/dark/icon_tile_map.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tile_set.svg b/editor/icons/dark/icon_tile_set.svg
deleted file mode 100644
index 547af99872..0000000000
--- a/editor/icons/dark/icon_tile_set.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm5 1v1 5 1h5c0.55228 0 1-0.44772 1-1v-5c0-0.55228-0.44772-1-1-1v4l-1-1-1 1v-4h-3zm-8 2v2h2v-2h-2zm3 0v2h2v-2h-2zm-3 3v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_timer.svg b/editor/icons/dark/icon_timer.svg
deleted file mode 100644
index 9efb856c7d..0000000000
--- a/editor/icons/dark/icon_timer.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="2" y="1037.4" width="12" height="2" ry="1" fill="#4f4f4f"/>
-<rect x="2" y="1049.4" width="12" height="2" ry="1" fill="#4f4f4f"/>
-<path d="m3 1050.4h10l-3-6h-4z" fill="#4f4f4f"/>
-<path d="m3 1038.4h10c0 2-3 4-4 6 1 2 4 4 4 6h-10c0-2 3-4 4-6-1-2-4-4-4-6z" fill="none" stroke="#4f4f4f" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tool_button.svg b/editor/icons/dark/icon_tool_button.svg
deleted file mode 100644
index db3fdb8c84..0000000000
--- a/editor/icons/dark/icon_tool_button.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="2" y="1047.4" width="6" height="4" ry="1.5" fill="#29d739"/>
-<rect x="1" y="1049.4" width="8" height="2" ry="0" fill="#29d739"/>
-<path d="m2 1042.4 3 2 3-2" fill="none" stroke="#29d739" stroke-linejoin="round" stroke-width="2"/>
-<path d="m5 1039.4v5" fill="none" stroke="#29d739" stroke-width="2"/>
-<g transform="translate(9,-1)" fill="#29d739">
-<path d="m2 1038.5c-1.1979 0.4235-1.999 1.5557-2 2.8262 9.552e-4 1.2705 0.80214 2.4027 2 2.8262v7.1738c0 0.554 0.446 1 1 1s1-0.446 1-1v-7.1758c1.1972-0.4232 1.9982-1.5544 2-2.8242-0.00178-1.2698-0.80282-2.401-2-2.8242v2.8242c0 0.5523-0.44772 1-1 1s-1-0.4477-1-1z" fill="#29d739"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tool_move.svg b/editor/icons/dark/icon_tool_move.svg
deleted file mode 100644
index e5452a5691..0000000000
--- a/editor/icons/dark/icon_tool_move.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9844 1.002a1.0001 1.0001 0 0 0 -0.69141 0.29102l-2 2 1.4141 1.4141 1.293-1.293 1.293 1.293 1.4141-1.4141-2-2a1.0001 1.0001 0 0 0 -0.72266 -0.29102zm-4.6914 4.291l-2 2a1.0001 1.0001 0 0 0 0 1.4141l2 2 1.4141-1.4141-1.293-1.293 1.293-1.293-1.4141-1.4141zm9.4141 0l-1.4141 1.4141 1.293 1.293-1.293 1.293 1.4141 1.4141 2-2a1.0001 1.0001 0 0 0 0 -1.4141l-2-2zm-4.707 0.70703a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-1.293 5.293l-1.4141 1.4141 2 2a1.0001 1.0001 0 0 0 1.4141 0l2-2-1.4141-1.4141-1.293 1.293-1.293-1.293z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tool_pan.svg b/editor/icons/dark/icon_tool_pan.svg
deleted file mode 100644
index c072e57b00..0000000000
--- a/editor/icons/dark/icon_tool_pan.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m6 8v7h6v-2h2v-5h-8z"/>
-<rect x="6" y="1039.4" width="2" height="8"/>
-<rect x="9" y="1038.4" width="2" height="8"/>
-<rect x="12" y="1040.4" width="2" height="8"/>
-<circle cx="7" cy="1039.4" r="1"/>
-<circle cx="10" cy="1038.4" r="1"/>
-<circle cx="13" cy="1040.4" r="1"/>
-<circle cx="12" cy="1049.4" r="2"/>
-<path d="m3.5251 1045.6c-0.52015-0.3803-1.1943-0.4556-1.6499 0-0.45566 0.4556-0.45564 1.1943-2.36e-5 1.6499l4.1248 4.1248 1.6499-2.7593z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tool_rotate.svg b/editor/icons/dark/icon_tool_rotate.svg
deleted file mode 100644
index 39a208bb2b..0000000000
--- a/editor/icons/dark/icon_tool_rotate.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8.0879 1.002a7 7 0 0 0 -0.30469 0.0019531 7 7 0 0 0 -0.69727 0.056641 7 7 0 0 0 -5.9512 5.5742 7 7 0 0 0 1.9707 6.3652h-1.1055v2h4a1.0001 1.0001 0 0 0 0.9707 -1.2422l-1-4-1.9414 0.48633 0.28125 1.1211a5 5 0 0 1 -1.3105 -3.3652 5 5 0 0 1 5 -5 5 5 0 0 1 5 5 5 5 0 0 1 -1.4668 3.5332l1.416 1.416a7 7 0 0 0 1.3281 -8.0449 7 7 0 0 0 -6.1895 -3.9023zm-0.087891 4.998a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#4f4f4f" fill-opacity=".99608" stroke-width="0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tool_scale.svg b/editor/icons/dark/icon_tool_scale.svg
deleted file mode 100644
index 823baf4dda..0000000000
--- a/editor/icons/dark/icon_tool_scale.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m9 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h2.5859l-1.293 1.293 1.4141 1.4141 1.293-1.293v2.5859a1 1 0 0 0 1 1 1 1 0 0 0 1 -1v-5a1.0001 1.0001 0 0 0 -1 -1h-5zm-1 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-6 2a1 1 0 0 0 -1 1v5a1.0001 1.0001 0 0 0 1 1h5a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-2.5859l1.293-1.293-1.4141-1.4141-1.293 1.293v-2.5859a1 1 0 0 0 -1 -1z" fill="#4f4f4f" fill-opacity=".99608" stroke-width="0"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tool_select.svg b/editor/icons/dark/icon_tool_select.svg
deleted file mode 100644
index cd2a4c9e28..0000000000
--- a/editor/icons/dark/icon_tool_select.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="translate(-26.001 -9.8683)">
-<path d="m40.001 1053.2-12-4.9365 4.9365 12 1.4207-4.2301 2.8254 2.8252 1.4127-1.4127-2.8254-2.8252z" fill="#4f4f4f"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tools.svg b/editor/icons/dark/icon_tools.svg
deleted file mode 100644
index 70da072dec..0000000000
--- a/editor/icons/dark/icon_tools.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 1l-1 2 1 2v4h-2v3 0.5c0 1.385 1.115 2.5 2.5 2.5s2.5-1.115 2.5-2.5v-1-2.5h-2v-4l1-2-1-2h-1zm6 0.17383a3 3 0 0 0 -2 2.8262 3 3 0 0 0 2 2.8262v6.1738 1c0 0.554 0.446 1 1 1s1-0.446 1-1v-4-3.1758a3 3 0 0 0 2 -2.8242 3 3 0 0 0 -2 -2.8242v2.8242a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-2.8262z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_touch_screen_button.svg b/editor/icons/dark/icon_touch_screen_button.svg
deleted file mode 100644
index b6b86bf781..0000000000
--- a/editor/icons/dark/icon_touch_screen_button.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a1 1 0 0 0 -1 1v2a1 1 0 0 0 1 1h2v-1h-1-1v-2h8v2h-2v1h2a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-8zm4 2a1 1 0 0 0 -1 1v7 0.033203l-2.4746-1.8086c-0.52015-0.3803-1.1948-0.4556-1.6504 0-0.45566 0.4556-0.45561 1.1948 0 1.6504l4.125 4.125h6c1.1046 0 2-0.8954 2-2v-5h-6v-4a1 1 0 0 0 -1 -1z" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_track_add_key.svg b/editor/icons/dark/icon_track_add_key.svg
deleted file mode 100644
index 91e4230cbe..0000000000
--- a/editor/icons/dark/icon_track_add_key.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path transform="translate(0 1044.4)" d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" fill="#00f010"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_track_add_key_hl.svg b/editor/icons/dark/icon_track_add_key_hl.svg
deleted file mode 100644
index f710873b43..0000000000
--- a/editor/icons/dark/icon_track_add_key_hl.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path transform="translate(0 1044.4)" d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" fill="#00f010"/>
-<path transform="translate(0 1044.4)" d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" fill="#000000" fill-opacity=".42424"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_track_continuous.svg b/editor/icons/dark/icon_track_continuous.svg
deleted file mode 100644
index a7b9b13a4c..0000000000
--- a/editor/icons/dark/icon_track_continuous.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<path d="m2 1050.4c6 0 6-4 12-4" fill="none" stroke="#4f4f4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_track_discrete.svg b/editor/icons/dark/icon_track_discrete.svg
deleted file mode 100644
index 0a5c875c40..0000000000
--- a/editor/icons/dark/icon_track_discrete.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)" fill="#4f4f4f">
-<circle cx="2" cy="1050.4" r="1"/>
-<circle cx="8" cy="1048.4" r="1"/>
-<circle cx="14" cy="1046.4" r="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_track_trigger.svg b/editor/icons/dark/icon_track_trigger.svg
deleted file mode 100644
index 439ef84961..0000000000
--- a/editor/icons/dark/icon_track_trigger.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="8" version="1.1" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)" fill="#4f4f4f">
-<circle cx="11" cy="1048.4" r="1"/>
-<circle cx="14" cy="1046.4" r="1"/>
-<rect x="1" y="1045.4" width="6" height="2"/>
-<rect x="3" y="1047.4" width="2" height="4"/>
-<circle cx="8" cy="1050.4" r="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_translation.svg b/editor/icons/dark/icon_translation.svg
deleted file mode 100644
index 131ed1b2d3..0000000000
--- a/editor/icons/dark/icon_translation.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 1v14h10a2 2 0 0 0 2 -2v-10a2 2 0 0 0 -2 -2v5 2l-2-2-2 2v-2-5h-6z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_transpose.svg b/editor/icons/dark/icon_transpose.svg
deleted file mode 100644
index 551c83137a..0000000000
--- a/editor/icons/dark/icon_transpose.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="1" y="1037.4" width="2" height="14"/>
-<rect x="1" y="1037.4" width="14" height="2"/>
-<rect x="1" y="1049.4" width="7" height="2"/>
-<rect x="6" y="1037.4" width="2" height="14"/>
-<rect x="1" y="1042.4" width="14" height="2"/>
-<rect transform="rotate(90)" x="1037.4" y="-15" width="7" height="2"/>
-<path d="m15 1051.4h-5l5-5z" fill-rule="evenodd"/>
-<rect x="8" y="1039.4" width="5" height="3"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tree.svg b/editor/icons/dark/icon_tree.svg
deleted file mode 100644
index 27855a9e6d..0000000000
--- a/editor/icons/dark/icon_tree.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="20" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<rect x="1" y="1037.4" width="14" height="2" fill="#29d739"/>
-<rect x="6" y="1041.4" width="9" height="2" fill="#29d739"/>
-<rect x="7" y="1045.4" width="8" height="2" fill="#29d739"/>
-<rect x="7" y="1049.4" width="8" height="2" fill="#29d739"/>
-<path d="m2 1038.4v4h4" fill="none" stroke="#29d739" stroke-linejoin="round" stroke-width="2"/>
-<path d="m6 1042.4v4h3" fill="none" stroke="#29d739" stroke-linejoin="round" stroke-width="2"/>
-<path d="m2 1040.4v10h7" fill="none" stroke="#29d739" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_tween.svg b/editor/icons/dark/icon_tween.svg
deleted file mode 100644
index 1d553c7a53..0000000000
--- a/editor/icons/dark/icon_tween.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7 1v2h6v6h2v-8h-8zm-1 4l1.793 1.793-4.793 4.793v-4.5859h-2v8h8v-2h-4.5859l4.793-4.793 1.793 1.793v-5h-5z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#bb6dff" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_unbone.svg b/editor/icons/dark/icon_unbone.svg
deleted file mode 100644
index 1d1fee54cc..0000000000
--- a/editor/icons/dark/icon_unbone.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m10.479 1a2.4664 2.4663 0 0 0 -1.7813 0.7207 2.4664 2.4663 0 0 0 -0.31445 3.1035l-1.0723 1.0723 2.791 2.791 1.0762-1.0742a2.4664 2.4663 0 0 0 3.0996 -0.31055 2.4664 2.4663 0 0 0 0 -3.4883 2.4664 2.4663 0 0 0 -1.3965 -0.69727 2.4664 2.4663 0 0 0 -0.69531 -1.3965 2.4664 2.4663 0 0 0 -1.707 -0.7207zm-4.582 6.3105l-1.0723 1.0742a2.4664 2.4663 0 0 0 -3.1016 0.3125 2.4664 2.4663 0 0 0 0 3.4883 2.4664 2.4663 0 0 0 1.3965 0.69531 2.4664 2.4663 0 0 0 0.69531 1.3965 2.4664 2.4663 0 0 0 3.4883 0 2.4664 2.4663 0 0 0 0.31445 -3.1035l1.0703-1.0723-2.791-2.791z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_ungroup.svg b/editor/icons/dark/icon_ungroup.svg
deleted file mode 100644
index 7bebe96e76..0000000000
--- a/editor/icons/dark/icon_ungroup.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m7 1037.4v6h-6v8h8v-6h6v-8zm2 2h4v4h-4z" fill="#4f4f4f" fill-opacity=".39216"/>
-<path transform="translate(0 1036.4)" d="m7 1v2c0 2.34e-5 0.446 0 1 0s1 2.34e-5 1 0v-2c0-2.341e-5 -0.446 0-1 0s-1-2.341e-5 -1 0zm6 0v2c0 2.34e-5 0.446 0 1 0s1 2.34e-5 1 0v-2c0-2.341e-5 -0.446 0-1 0s-1-2.341e-5 -1 0zm-12 6v2c0 2.34e-5 0.446 0 1 0s1 2.34e-5 1 0v-2c0-2.34e-5 -0.446 0-1 0s-1-2.34e-5 -1 0zm6 0v2c0 2.34e-5 0.446 0 1 0s1 2.34e-5 1 0v-2c0-2.34e-5 -0.446 0-1 0s-1-2.34e-5 -1 0zm6 0v2c0 2.34e-5 0.446 0 1 0s1 2.34e-5 1 0v-2c0-2.34e-5 -0.446 0-1 0s-1-2.34e-5 -1 0zm-12 6v2c0 2.3e-5 0.446 0 1 0s1 2.3e-5 1 0v-2c0-2.3e-5 -0.446 0-1 0s-1-2.3e-5 -1 0zm6 0v2c0 2.3e-5 0.446 0 1 0s1 2.3e-5 1 0v-2c0-2.3e-5 -0.446 0-1 0s-1-2.3e-5 -1 0z" fill="#000000"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_unlock.svg b/editor/icons/dark/icon_unlock.svg
deleted file mode 100644
index 1eb65383a5..0000000000
--- a/editor/icons/dark/icon_unlock.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m2 8v7h12v-7h-12zm5 2h2v3h-2v-3z"/>
-<path transform="translate(0 1036.4)" d="m8 1c-0.87738 0.001545-1.7389 0.23394-2.498 0.67383l1 1.7324c0.45506-0.26449 0.97171-0.40459 1.498-0.40625 1.6569 0 3 1.3431 3 3h2c0-2.7614-2.2386-5-5-5z"/>
-<rect x="11" y="1042.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_uv.svg b/editor/icons/dark/icon_uv.svg
deleted file mode 100644
index 15e76053e0..0000000000
--- a/editor/icons/dark/icon_uv.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 5v4a3 3 0 0 0 1.5 2.5977 3 3 0 0 0 3 0 3 3 0 0 0 1.5 -2.5977v-4h-2v4a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-4h-2zm8 0l2 7h1 1 1l2-7h-2l-1.5 5.25-1.5-5.25h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_v_box_container.svg b/editor/icons/dark/icon_v_box_container.svg
deleted file mode 100644
index 8cabe8a4a1..0000000000
--- a/editor/icons/dark/icon_v_box_container.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m15 1039.4c0-1.1046-0.89543-2-2-2h-10c-1.1046 0-2 0.8954-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-10zm-2 0v2h-10v-2h10zm0 4v2h-10v-2h10zm0 4v2h-10v-2h10z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_v_button_array.svg b/editor/icons/dark/icon_v_button_array.svg
deleted file mode 100644
index 9c2e5cecc6..0000000000
--- a/editor/icons/dark/icon_v_button_array.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m7 1v2.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-2.1328h-2zm-0.5 6c-0.831 0-1.5 0.669-1.5 1.5v0.5h-1v2h2v-2h4v2h2v-2h-1v-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z"/>
-<path d="m7 1046.4v2h-2v2h2v2h2v-2h2v-2h-2v-2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_v_scroll_bar.svg b/editor/icons/dark/icon_v_scroll_bar.svg
deleted file mode 100644
index 3ea3a124c6..0000000000
--- a/editor/icons/dark/icon_v_scroll_bar.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m5 1c-1.108 0-2 0.89199-2 2v10c0 1.108 0.89199 2 2 2h6c1.108 0 2-0.89199 2-2v-10c0-1.108-0.89199-2-2-2h-6zm2.9883 1a1.0001 1.0001 0 0 1 0.56641 0.16797l3 2a1.0001 1.0001 0 1 1 -1.1094 1.6641l-2.4453-1.6289-2.4453 1.6289a1.0001 1.0001 0 1 1 -1.1094 -1.6641l3-2a1.0001 1.0001 0 0 1 0.54297 -0.16797zm-2.998 7.9922a1.0001 1.0001 0 0 1 0.56445 0.17578l2.4453 1.6309 2.4453-1.6309a1.0001 1.0001 0 1 1 1.1094 1.6641l-3 2a1.0001 1.0001 0 0 1 -1.1094 0l-3-2a1.0001 1.0001 0 0 1 0.54492 -1.8398z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_v_separator.svg b/editor/icons/dark/icon_v_separator.svg
deleted file mode 100644
index c9d6b879a4..0000000000
--- a/editor/icons/dark/icon_v_separator.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1047.4h3v-6h-3v6zm5 4h2v-14h-2v14zm4-4h3v-6h-3v6z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_v_slider.svg b/editor/icons/dark/icon_v_slider.svg
deleted file mode 100644
index 0ef58d34e5..0000000000
--- a/editor/icons/dark/icon_v_slider.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m6 1050.4a1.0001 1.0001 0 1 1 -2 0v-2.1308a4 4 0 0 0 1 0.1308 4 4 0 0 0 1 -0.1328zm0-9.8691a4 4 0 0 0 -1 -0.1309 4 4 0 0 0 -1 0.1329v-2.1329a1.0001 1.0001 0 1 1 2 0z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#29d739" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-<circle transform="matrix(0,-1,-1,0,0,0)" cx="-1039.4" cy="-5" r="2" fill="#29d739"/>
-<path d="m12 1038.4h-2" fill="none" stroke="#29d739" stroke-linecap="round" stroke-width="2"/>
-<path d="m11 1044.4v0" fill="none" stroke="#29d739" stroke-linecap="round" stroke-width="2"/>
-<path d="m12 1050.4h-2" fill="none" stroke="#29d739" stroke-linecap="round" stroke-width="2"/>
-<path d="m6 1049.4h-2v-6.1308a4 4 0 0 0 1 0.1308 4 4 0 0 0 1 -0.1328z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_v_split_container.svg b/editor/icons/dark/icon_v_split_container.svg
deleted file mode 100644
index 4ad51b4fbe..0000000000
--- a/editor/icons/dark/icon_v_split_container.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#29d739">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z"/>
-<rect transform="rotate(90)" x="1043.4" y="-13" width="2" height="10"/>
-<path d="m10 1045.4h-4l2 2z"/>
-<path d="m10 1043.4-2-2-2 2z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_variant.svg b/editor/icons/dark/icon_variant.svg
deleted file mode 100644
index dded24a52d..0000000000
--- a/editor/icons/dark/icon_variant.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="translate(0,-3)" fill="#4f4f4f">
-<rect x="3" y="1044.4" width="2" height="6"/>
-<rect x="6" y="1044.4" width="2" height="6"/>
-<rect x="3" y="1044.4" width="1" height="2"/>
-<path d="m3 1044.4a3 3 0 0 0 -3 3h2a1 1 0 0 1 1 -1z"/>
-<path d="m14 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1z"/>
-<rect transform="scale(1,-1)" x="14" y="-1052.4" width="2" height="8"/>
-<rect transform="scale(1,-1)" x="11" y="-1047.4" width="2" height="3"/>
-<path d="m3 1050.4a3 3 0 0 1 -3 -3h2a1 1 0 0 0 1 1z"/>
-<path d="m8 1044.4a3 3 0 0 1 3 3h-2a1 1 0 0 0 -1 -1z"/>
-<rect x="9" y="1047.4" width="2" height="3"/>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_vector.svg b/editor/icons/dark/icon_vector.svg
deleted file mode 100644
index dda46edeaa..0000000000
--- a/editor/icons/dark/icon_vector.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)" fill="none" stroke="#b8ea68" stroke-width="2">
-<path d="m7 1047.4-4 4"/>
-<path d="m7 1040.4v7h7"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_vector2.svg b/editor/icons/dark/icon_vector2.svg
deleted file mode 100644
index ab92e7bb60..0000000000
--- a/editor/icons/dark/icon_vector2.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1040.4)">
-<path d="m4 1041.4v9h9" fill="none" stroke="#b8ea68" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_vehicle_body.svg b/editor/icons/dark/icon_vehicle_body.svg
deleted file mode 100644
index 1afbe9229d..0000000000
--- a/editor/icons/dark/icon_vehicle_body.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m5 3a1 1 0 0 0 -1 1l-1 3h-2v4h1.0508c0.23167-1.1411 1.2398-2 2.4492-2s2.2175 0.85893 2.4492 2h2.1016c0.23167-1.1411 1.2398-2 2.4492-2s2.2175 0.85893 2.4492 2h1.0508v-4h-4v-4h-6zm1 1h4v3h-4v-3z"/>
-<circle cx="4.5" cy="1047.9" r="1.5"/>
-<circle cx="11.5" cy="1047.9" r="1.5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_vehicle_wheel.svg b/editor/icons/dark/icon_vehicle_wheel.svg
deleted file mode 100644
index 40f28709bc..0000000000
--- a/editor/icons/dark/icon_vehicle_wheel.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5 -5 5 5 0 0 1 5 -5z"/>
-<path transform="translate(0 1036.4)" d="m8 4a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_video_player.svg b/editor/icons/dark/icon_video_player.svg
deleted file mode 100644
index 1cfd25eea3..0000000000
--- a/editor/icons/dark/icon_video_player.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="2" y="1038.4" width="12" height="12" ry="1" fill="none" stroke="#29d739" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m6 1045.4v-4l4 2z" fill="#29d739" fill-rule="evenodd"/>
-<rect x="3" y="1047.4" width="10" height="2" ry="0" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_viewport.svg b/editor/icons/dark/icon_viewport.svg
deleted file mode 100644
index 6e583ca62f..0000000000
--- a/editor/icons/dark/icon_viewport.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v8c8.03e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h10c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v8c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-8c9.6e-6 -0.55228 0.44772-0.99999 1-1z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_viewport_container.svg b/editor/icons/dark/icon_viewport_container.svg
deleted file mode 100644
index 3518756177..0000000000
--- a/editor/icons/dark/icon_viewport_container.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10zm3 1c-0.5304 1e-4 -1.0391 0.21084-1.4141 0.58594-0.37509 0.375-0.58586 0.88366-0.58594 1.4141v4c8e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.3751 0.88366 0.58584 1.4141 0.58594h4c1.1046 0 2-0.8954 2-2v-4c0-1.1046-0.89543-2-2-2zm0 1h4c0.55228 0 0.99999 0.4477 1 1v4c-1e-5 0.5523-0.44772 1-1 1h-4c-0.55228 0-0.99999-0.4477-1-1v-4c1e-5 -0.5523 0.44772-1 1-1z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_viewport_sprite.svg b/editor/icons/dark/icon_viewport_sprite.svg
deleted file mode 100644
index e2addce984..0000000000
--- a/editor/icons/dark/icon_viewport_sprite.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="20" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<path transform="translate(0 1036.4)" d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v8c8.03e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h10c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v8c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-8c9.6e-6 -0.55228 0.44772-0.99999 1-1z" fill="#6d90ff" fill-opacity=".98824"/>
-<rect x="4" y="1042.4" width="2" height="2" fill="#6d90ff" fill-opacity=".98824"/>
-<rect x="10" y="1042.4" width="2" height="2" fill="#6d90ff" fill-opacity=".98824"/>
-<rect x="4" y="1045.4" width="8" height="1" fill="#6d90ff" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_viewport_texture.svg b/editor/icons/dark/icon_viewport_texture.svg
deleted file mode 100644
index c4e2a2dbda..0000000000
--- a/editor/icons/dark/icon_viewport_texture.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v8c8.03e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h10c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2h-10zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v8c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-8c9.6e-6 -0.55228 0.44772-0.99999 1-1zm6 3v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-1-1h-1v-1h-1z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_visibility_enabler.svg b/editor/icons/dark/icon_visibility_enabler.svg
deleted file mode 100644
index 0bc3449b07..0000000000
--- a/editor/icons/dark/icon_visibility_enabler.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<g transform="translate(-.00015202)">
-<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle cx="8" cy="1044.4" r="2"/>
-</g>
-<path transform="translate(0 1036.4)" d="m1 1v3h1v-2h2v-1h-3zm11 0v1h2v2h1v-3h-3zm-11 11v3h3v-1h-2v-2h-1zm13 0v2h-2v1h3v-3h-1z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_visibility_enabler_2d.svg b/editor/icons/dark/icon_visibility_enabler_2d.svg
deleted file mode 100644
index 23a66501f7..0000000000
--- a/editor/icons/dark/icon_visibility_enabler_2d.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff" fill-opacity=".98824">
-<g transform="translate(-.00015202)">
-<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle cx="8" cy="1044.4" r="2"/>
-</g>
-<path transform="translate(0 1036.4)" d="m1 1v3h1v-2h2v-1h-3zm11 0v1h2v2h1v-3h-3zm-11 11v3h3v-1h-2v-2h-1zm13 0v2h-2v1h3v-3h-1z"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_visibility_notifier.svg b/editor/icons/dark/icon_visibility_notifier.svg
deleted file mode 100644
index d4c56afd65..0000000000
--- a/editor/icons/dark/icon_visibility_notifier.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff5f5f" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m8 3c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-0.65207 4.7109-2h-0.71094-2v-0.54102a4 4 0 0 1 -2 0.54102 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4 4 4 0 0 1 2 0.54102v-2.1816c-0.68312-0.23834-1.3644-0.35938-2-0.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<rect x="12" y="1037.4" width="2" height="6"/>
-<rect transform="scale(1,-1)" x="12" y="-1047.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_visibility_notifier_2d.svg b/editor/icons/dark/icon_visibility_notifier_2d.svg
deleted file mode 100644
index c84c2dbfca..0000000000
--- a/editor/icons/dark/icon_visibility_notifier_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m12 1v6h2v-6h-2zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-0.65207 4.7109-2h-0.71094-2v-0.54102a4 4 0 0 1 -2 0.54102 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4 4 4 0 0 1 2 0.54102v-2.1816c-0.68312-0.23834-1.3644-0.35938-2-0.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm4 2v2h2v-2h-2z" color="#000000" color-rendering="auto" fill="#6d90ff" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_visible.svg b/editor/icons/dark/icon_visible.svg
deleted file mode 100644
index 784cd15d1e..0000000000
--- a/editor/icons/dark/icon_visible.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" color="#000000" color-rendering="auto" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle cx="8" cy="1044.4" r="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_visual_script.svg b/editor/icons/dark/icon_visual_script.svg
deleted file mode 100644
index 96fcca46ab..0000000000
--- a/editor/icons/dark/icon_visual_script.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<ellipse cx="3" cy="1039.4" r="2" fill="#6e6e6e"/>
-<path transform="translate(0 1036.4)" d="m7 1l-0.56445 2.2578a5 5 0 0 0 -0.68945 0.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -0.28516 0.68555l-2.2539 0.5625v2h5.2715a2 2 0 0 1 -0.27148 -1 2 2 0 0 1 2 -2 2 2 0 0 1 2 2 2 2 0 0 1 -0.26953 1h5.2695v-2l-2.2578-0.56445a5 5 0 0 0 -0.2793 -0.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -0.68555 -0.28516l-0.5625-2.2539h-2zm-4 9v6h2a3 3 0 0 0 3 -3v-3h-2v3a1 1 0 0 1 -1 1v-4h-2zm8 0a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324 -1 2 2 0 0 0 0 -2 2 2 0 0 0 -1.7324 -1h2v-2h-2z" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_visual_shader_port.svg b/editor/icons/dark/icon_visual_shader_port.svg
deleted file mode 100644
index 0f5d00dbc4..0000000000
--- a/editor/icons/dark/icon_visual_shader_port.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="10" height="10" version="1.1" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1042.4)">
-<path d="m2 1051.4v-8l6 4z" fill="#f3f3f3" fill-rule="evenodd" stroke="#e4e4e4" stroke-linejoin="round" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_vu_empty.svg b/editor/icons/dark/icon_vu_empty.svg
deleted file mode 100644
index ae2163a386..0000000000
--- a/editor/icons/dark/icon_vu_empty.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="128" height="4" version="1.1" viewBox="0 0 128 4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x2="128" y1="2" y2="2" gradientUnits="userSpaceOnUse">
-<stop stop-color="#00f010" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#ff4040" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1048.4)">
-<path transform="translate(0 1048.4)" d="m2 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2h75 3 2 3 15v-4h-15-3-2-3-75zm100 0v4h24a2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2h-24z" fill="url(#a)"/>
-<path transform="translate(0 1048.4)" d="m2 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2h75 3 2 3 15v-4h-15-3-2-3-75zm100 0v4h24a2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2h-24z" fill-opacity=".23529"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_vu_full.svg b/editor/icons/dark/icon_vu_full.svg
deleted file mode 100644
index e4035026d7..0000000000
--- a/editor/icons/dark/icon_vu_full.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="128" height="4" version="1.1" viewBox="0 0 128 4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x2="128" y1="2" y2="2" gradientUnits="userSpaceOnUse">
-<stop stop-color="#00f010" offset="0"/>
-<stop stop-color="#d6cf4b" offset=".5"/>
-<stop stop-color="#ff4040" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -1048.4)">
-<path transform="translate(0 1048.4)" d="m2 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2h75 3 2 3 15v-4h-15-3-2-3-75zm100 0v4h24a2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2h-24z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_warning.svg b/editor/icons/dark/icon_warning.svg
deleted file mode 100644
index 0dec9c7bd4..0000000000
--- a/editor/icons/dark/icon_warning.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect y="1044.4" width="8" height="8" ry="4" fill="#fea900"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_window_dialog.svg b/editor/icons/dark/icon_window_dialog.svg
deleted file mode 100644
index 39d231df9a..0000000000
--- a/editor/icons/dark/icon_window_dialog.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.8954-2 2v1h14v-1c0-1.1046-0.89543-2-2-2h-10zm9 1h1v1h-1v-1zm-11 3v8c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-8h-14z" fill="#29d739"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_world.svg b/editor/icons/dark/icon_world.svg
deleted file mode 100644
index 92e3529efc..0000000000
--- a/editor/icons/dark/icon_world.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<circle cx="6" cy="1046.4" r="5"/>
-<circle cx="12" cy="1039.4" r="1"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_world_2d.svg b/editor/icons/dark/icon_world_2d.svg
deleted file mode 100644
index e728ed313c..0000000000
--- a/editor/icons/dark/icon_world_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2 1037.4a1.0001 1.0001 0 0 0 -1 1v10a1.0001 1.0001 0 0 0 1 1c2.3667 0 3.9746 0.4629 5.7246 0.9629s3.6421 1.0371 6.2754 1.0371a1.0001 1.0001 0 0 0 1 -1v-10a1.0001 1.0001 0 0 0 -1 -1c-2.3667 0-3.9746-0.4609-5.7246-0.9609-1.75-0.5-3.6421-1.0391-6.2754-1.0391zm1 2.0957c1.7984 0.1158 3.2574 0.448 4.7246 0.8672 1.4977 0.4279 3.194 0.8188 5.2754 0.9414v8.002c-1.7985-0.1158-3.2574-0.448-4.7246-0.8672-1.4977-0.4279-3.194-0.8208-5.2754-0.9434v-8z" color="#000000" color-rendering="auto" fill="#4f4f4f" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_world_environment.svg b/editor/icons/dark/icon_world_environment.svg
deleted file mode 100644
index c80e78f178..0000000000
--- a/editor/icons/dark/icon_world_environment.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#ff5f5f" stroke-opacity=".99608">
-<circle cx="8" cy="1044.4" r="6" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m2 1044.4c4.5932 1.582 8.3985 1.0627 12 0" stroke-width="1.5"/>
-<path d="m8 1038.4c-3 4-3 8 0 12" stroke-width="1.5"/>
-<path d="m8 1038.4c3 4 3 8 0 12" stroke-width="1.5"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_y_sort.svg b/editor/icons/dark/icon_y_sort.svg
deleted file mode 100644
index 914ecfed0d..0000000000
--- a/editor/icons/dark/icon_y_sort.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#6d90ff" fill-opacity=".98824">
-<rect x="9" y="1038.4" width="6" height="2"/>
-<path d="m3 1048.4h-2l3 3 3-3h-2v-8h2l-3-3-3 3h2z"/>
-<rect x="9" y="1043.4" width="4" height="2"/>
-<rect x="9" y="1048.4" width="2" height="2"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_zoom.svg b/editor/icons/dark/icon_zoom.svg
deleted file mode 100644
index ac185d3c9e..0000000000
--- a/editor/icons/dark/icon_zoom.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 2.752 -0.83398l4.3184 4.3184 1.4141-1.4141-4.3184-4.3184a5 5 0 0 0 0.41016 -0.75195h-0.57617v-2h-1a3 3 0 0 1 -3 3 3 3 0 0 1 -3 -3 3 3 0 0 1 3 -3 3 3 0 0 1 2 0.76758v-1.7676h0.99023a5 5 0 0 0 -2.9902 -1zm5 0v2h-2v2h2v2h2v-2h2v-2h-2v-2h-2z" fill="#4f4f4f" fill-opacity=".99608"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_zoom_less.svg b/editor/icons/dark/icon_zoom_less.svg
deleted file mode 100644
index ea7190c4ca..0000000000
--- a/editor/icons/dark/icon_zoom_less.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="1" y="1043.4" width="14" height="1.9999" fill="#4f4f4f"/>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_zoom_more.svg b/editor/icons/dark/icon_zoom_more.svg
deleted file mode 100644
index 046b569c1a..0000000000
--- a/editor/icons/dark/icon_zoom_more.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<g transform="translate(-201.58 205.03)">
-<g transform="matrix(48.459 0 0 53.968 -126.63 -55836)">
-<g transform="translate(.51853 -.019888)" fill="#4f4f4f" fill-opacity=".99608">
-<rect x="6.3979" y="1050.1" width=".042995" height=".26205" rx="0" ry="0"/>
-<rect x="6.2806" y="1050.2" width=".28011" height=".040944" rx="0" ry="0"/>
-</g>
-</g>
-</g>
-</g>
-</svg>
diff --git a/editor/icons/dark/icon_zoom_reset.svg b/editor/icons/dark/icon_zoom_reset.svg
deleted file mode 100644
index bb262bca9d..0000000000
--- a/editor/icons/dark/icon_zoom_reset.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#4f4f4f">
-<rect x="3" y="1037.4" width="2" height="14"/>
-<rect x="12" y="1037.4" width="2" height="14"/>
-<rect x="7" y="1046.4" width="2" height="2"/>
-<rect x="7" y="1040.4" width="2" height="2"/>
-<path d="m1 1040.4 2-3h2v3z" fill-rule="evenodd"/>
-<path d="m10 1040.4 2-3h2v3z" fill-rule="evenodd"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_array_mesh.svg b/editor/icons/icon_array_mesh.svg
new file mode 100644
index 0000000000..68890c4366
--- /dev/null
+++ b/editor/icons/icon_array_mesh.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_audio_effect_amplify.svg b/editor/icons/icon_audio_effect_amplify.svg
index 1cb9be9b10..20612bbaf3 100644
--- a/editor/icons/icon_audio_effect_amplify.svg
+++ b/editor/icons/icon_audio_effect_amplify.svg
@@ -7,6 +7,6 @@
</linearGradient>
</defs>
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m15 1-14 7h14zm-13 9v1h2v-1zm2 1v1h-2v-1h-1v4h1v-2h2v2h1v-4zm2-1v5h1v-4h1v4h1v-4h1v-1zm4 1v4h1v-4zm2-1v5h1v-2h2v-3zm1 1h1v1h-1z" fill="url(#a)"/>
+<path transform="translate(0 1036.4)" d="m2 1v8h2v-2h2v-2h-2v-2h3v-2zm6 0 2 4-2 4h2l1-2 1 2h2l-2-4 2-4h-2l-1 2-1-2zm-6 9v1h2v-1zm2 1v1h-2v-1h-1v4h1v-2h2v2h1v-4zm2-1v5h1v-4h1v4h1v-4h1v-1zm4 1v4h1v-4zm2-1v5h1v-2h2v-3zm1 1h1v1h-1z" fill="url(#a)"/>
</g>
</svg>
diff --git a/editor/icons/icon_clear.svg b/editor/icons/icon_clear.svg
new file mode 100644
index 0000000000..533054e37b
--- /dev/null
+++ b/editor/icons/icon_clear.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m8 1a1 1 0 0 0 -1 1v5h-2c-1.108 0-2 0.892-2 2v1h10v-1c0-1.108-0.892-2-2-2h-2v-5a1 1 0 0 0 -1 -1zm-5 10v4l10-1v-3h-10z" fill="#e0e0e0" fill-opacity=".99608"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_collision_2d.svg b/editor/icons/icon_collision_polygon_2d.svg
index 9d90a66c6f..9d90a66c6f 100644
--- a/editor/icons/icon_collision_2d.svg
+++ b/editor/icons/icon_collision_polygon_2d.svg
diff --git a/editor/icons/icon_cube_mesh.svg b/editor/icons/icon_cube_mesh.svg
index 0ed3e5e12f..45275216ab 100644
--- a/editor/icons/icon_cube_mesh.svg
+++ b/editor/icons/icon_cube_mesh.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 14.999999 14.999999" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1037.4)">
-<path d="m7.5 1038.2-6.5625 3.2804v6.772l0.49015 0.246 6.0723 3.0344 6.5625-3.2804v-6.772zm0 1.9831 3.6926 1.8463-3.6926 1.8463-3.6926-1.8463zm-4.7889 3.2804 3.9022 1.9502v3.6944l-3.9022-1.952zm9.5779 0v3.6926l-3.9022 1.952v-3.6944z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path d="m7.5 1038.2-6.5625 3.2804v6.772l6.5625 3.2804 6.5625-3.2804v-6.772zm0 1.9831 3.6926 1.8463-3.6926 1.8463-3.6926-1.8463zm-4.7889 3.2804 3.9022 1.9502v3.6944l-3.9022-1.952zm9.5779 0v3.6926l-3.9022 1.952v-3.6944z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_file_big_broken.svg b/editor/icons/icon_file_big_broken.svg
new file mode 100644
index 0000000000..167bb1bb5f
--- /dev/null
+++ b/editor/icons/icon_file_big_broken.svg
@@ -0,0 +1,7 @@
+<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -988.36)">
+<g transform="translate(0 -1.6949e-5)">
+<path transform="translate(0 988.36)" d="m14 5c-2.1987 0-4 1.8013-4 4v26.172a1.0001 1.0001 0 0 0 1.707 0.70703l3.293-3.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l8-8a1.0001 1.0001 0 0 0 0.29297 -0.70703v-11.172a1.0001 1.0001 0 0 0 -0.29297 -0.70703l-16-16a1.0001 1.0001 0 0 0 -0.70703 -0.29297h-23zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v9.7578l-7 7-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-2.293 2.293v-23.758c0-1.1253 0.87473-2 2-2zm0.98438 28.83a1.0001 1.0001 0 0 0 -0.69141 0.29297l-4 4a1.0001 1.0001 0 0 0 -0.29297 0.70703v14.17c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-16.17a1.0001 1.0001 0 0 0 -1.707 -0.70703l-7.293 7.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -0.72266 -0.29297zm0.015625 2.4141l9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l6.293-6.293v13.756c0 1.1253-0.87473 2-2 2h-36c-1.1253 0-2-0.87473-2-2v-13.756l3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff8484" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</g>
+</g>
+</svg>
diff --git a/editor/icons/icon_file_big_dead.svg b/editor/icons/icon_file_big_dead.svg
new file mode 100644
index 0000000000..c8aab912f1
--- /dev/null
+++ b/editor/icons/icon_file_big_dead.svg
@@ -0,0 +1,7 @@
+<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -988.36)">
+<g transform="translate(0 -1.6949e-5)">
+<path d="m14 993.36c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-0.0078c2e-3 -0.2483-0.0793-0.501-0.28516-0.707l-16-16c-0.18788-0.18693-0.44247-0.28939-0.70704-0.28907v-4e-3zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v32c0 1.1253-0.87472 2-2 2h-36c-1.1253 0-2-0.8747-2-2v-46c0-1.1253 0.87472-2 2-2zm2.9512 22.002a1 1 0 0 0 -0.60938 0.2461 1 1 0 0 0 -0.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 0.09375 1.4121 1 1 0 0 0 1.4102 -0.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102 0.094 1 1 0 0 0 0.09375 -1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -0.09375 -1.4121 1 1 0 0 0 -0.63867 -0.2461 1 1 0 0 0 -0.77148 0.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -0.80078 -0.3398zm23 0a1 1 0 0 0 -0.60938 0.2461 1 1 0 0 0 -0.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 0.09375 1.4121 1 1 0 0 0 1.4102 -0.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102 0.094 1 1 0 0 0 0.09375 -1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -0.09375 -1.4121 1 1 0 0 0 -0.63867 -0.2461 1 1 0 0 0 -0.77148 0.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -0.80078 -0.3398zm-18.951 13.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h3v3c0 2.7527 2.2473 5 5 5s5-2.2473 5-5v-3h9a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm5 2h6v3c0 1.6793-1.3207 3-3 3s-3-1.3207-3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff8484" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</g>
+</g>
+</svg>
diff --git a/editor/icons/icon_file_broken.svg b/editor/icons/icon_file_broken.svg
new file mode 100644
index 0000000000..f352eeb001
--- /dev/null
+++ b/editor/icons/icon_file_broken.svg
@@ -0,0 +1,7 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<g transform="translate(0 -1.6949e-5)">
+<path transform="translate(0 1036.4)" d="m2 1v8.5859l1.293-1.293a1.0001 1.0001 0 0 1 0.69141 -0.29102 1.0001 1.0001 0 0 1 0.72266 0.29102l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 1.4141 0l2.293 2.293 1-1v-3.5859h-5v-5h-7zm8 0v4h4l-4-4zm-6 9.4141l-2 2v2.5859h12v-2.5859l-0.29297 0.29297a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293-2.293 2.293a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293z" fill="#ff8484"/>
+</g>
+</g>
+</svg>
diff --git a/editor/icons/icon_gizmo_camera.svg b/editor/icons/icon_gizmo_camera.svg
new file mode 100644
index 0000000000..f6e5f885e7
--- /dev/null
+++ b/editor/icons/icon_gizmo_camera.svg
@@ -0,0 +1,5 @@
+<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -924.36)">
+<path d="m76 944.36a24 24 0 0 0 -23.906 22.219 24 24 0 0 0 -16.094 -6.2192 24 24 0 0 0 -24 24 24 24 0 0 0 16 22.594v17.406c0 4.432 3.5679 8 8 8h48c4.4321 0 8-3.568 8-8v-8l24 16v-48l-24 16v-14.156a24 24 0 0 0 8 -17.844 24 24 0 0 0 -24 -24z" fill="#f7f5cf"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gizmo_directional_light.svg b/editor/icons/icon_gizmo_directional_light.svg
index a8739a5a78..f7fa732501 100644
--- a/editor/icons/icon_gizmo_directional_light.svg
+++ b/editor/icons/icon_gizmo_directional_light.svg
@@ -1,5 +1,5 @@
<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m64 4a8 8 0 0 0 -8 8v12a8 8 0 0 0 8 8 8 8 0 0 0 8 -8v-12a8 8 0 0 0 -8 -8zm-36.887 15.23a8 8 0 0 0 -5.5391 2.3438 8 8 0 0 0 0 11.312l8.4844 8.4863a8 8 0 0 0 11.314 0 8 8 0 0 0 0 -11.314l-8.4863-8.4844a8 8 0 0 0 -5.7734 -2.3438zm73.539 0a8 8 0 0 0 -5.5391 2.3438l-8.4863 8.4844a8 8 0 0 0 0 11.314 8 8 0 0 0 11.314 0l8.4844-8.4863a8 8 0 0 0 0 -11.312 8 8 0 0 0 -5.7734 -2.3438zm-36.652 20.77a24 24 0 0 0 -24 24 24 24 0 0 0 24 24 24 24 0 0 0 24 -24 24 24 0 0 0 -24 -24zm-52 16a8 8 0 0 0 -8 8 8 8 0 0 0 8 8h12a8 8 0 0 0 8 -8 8 8 0 0 0 -8 -8h-12zm92 0a8 8 0 0 0 -8 8 8 8 0 0 0 8 8h12a8 8 0 0 0 8 -8 8 8 0 0 0 -8 -8h-12zm-68.4 28.285a8 8 0 0 0 -5.541 2.3418l-8.4844 8.4863a8 8 0 0 0 0 11.312 8 8 0 0 0 11.312 0l8.4863-8.4844a8 8 0 0 0 0 -11.314 8 8 0 0 0 -5.7734 -2.3418zm56.568 0a8 8 0 0 0 -5.541 2.3418 8 8 0 0 0 0 11.314l8.4863 8.4844a8 8 0 0 0 11.312 0 8 8 0 0 0 0 -11.312l-8.4844-8.4863a8 8 0 0 0 -5.7734 -2.3418zm-28.168 11.715a8 8 0 0 0 -8 8v12a8 8 0 0 0 8 8 8 8 0 0 0 8 -8v-12a8 8 0 0 0 -8 -8z" fill="#f7f5cf"/>
+<path transform="translate(0 924.36)" d="m64 8c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4zm-36.77 15.227c-1.0225 0-2.0447 0.39231-2.8281 1.1758-1.5669 1.5669-1.5669 4.0893 0 5.6562l11.312 11.314c1.5669 1.5669 4.0913 1.5669 5.6582 0s1.5669-4.0913 0-5.6582l-11.314-11.312c-0.78348-0.78348-1.8056-1.1758-2.8281-1.1758zm73.539 0c-1.0225 0-2.0446 0.39231-2.8281 1.1758l-11.314 11.312c-1.5669 1.5669-1.5669 4.0913 0 5.6582s4.0913 1.5669 5.6582 0l11.313-11.314c1.5669-1.5669 1.5669-4.0893 0-5.6562-0.78348-0.78348-1.8056-1.1758-2.8281-1.1758zm-36.77 20.773c-11.046 1e-5 -20 8.9543-20 20 7e-6 11.046 8.9543 20 20 20s20-8.9543 20-20c-8e-6 -11.046-8.9543-20-20-20zm-52 16c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4h-16zm88 0c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4h-16zm-61.455 25.453c-1.0225 0-2.0466 0.39035-2.8301 1.1738l-11.312 11.314c-1.5669 1.5669-1.5669 4.0893 0 5.6563 1.5669 1.5669 4.0893 1.5669 5.6562 0l11.314-11.313c1.5669-1.5669 1.5669-4.0913 0-5.6582-0.78347-0.78347-1.8056-1.1738-2.8281-1.1738zm50.91 0c-1.0225 0-2.0447 0.39035-2.8281 1.1738-1.5669 1.5669-1.5669 4.0913 0 5.6582l11.314 11.313c1.5669 1.5669 4.0893 1.5669 5.6563 0 1.5669-1.567 1.5669-4.0893 0-5.6563l-11.313-11.314c-0.78347-0.78347-1.8076-1.1738-2.8301-1.1738zm-25.455 10.547c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4z" fill="#f7f5cf"/>
</g>
</svg>
diff --git a/editor/icons/icon_gizmo_g_i_probe.svg b/editor/icons/icon_gizmo_g_i_probe.svg
new file mode 100644
index 0000000000..7d3adf4196
--- /dev/null
+++ b/editor/icons/icon_gizmo_g_i_probe.svg
@@ -0,0 +1,5 @@
+<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -924.36)">
+<path transform="translate(0 924.36)" d="m12 8a4.0004 4.0004 0 0 0 -4 4v104a4.0004 4.0004 0 0 0 4 4h60v-8h-56v-96h96v8h8v-12a4.0004 4.0004 0 0 0 -4 -4h-104zm27.715 17.951c-1.2324 0.086154-2.3996 0.76492-3.0664 1.9199l-0.14844 0.25781c-1.0669 1.848-0.43784 4.1948 1.4102 5.2617l10.648 6.1484c1.848 1.0669 4.1948 0.43784 5.2617-1.4102l0.14844-0.25781c1.0669-1.848 0.43784-4.1948-1.4102-5.2617l-10.648-6.1484c-0.693-0.4001-1.4558-0.56146-2.1953-0.50977zm52.285 2.0488a32 32 0 0 0 -32 32 32 32 0 0 0 16 27.668v8.332c0 4.432 3.568 8 8 8h16c4.432 0 8-3.568 8-8v-8.3223a32 32 0 0 0 16 -27.678 32 32 0 0 0 -32 -32zm0 12a20 20 0 0 1 20 20 20 20 0 0 1 -20 20 20 20 0 0 1 -20 -20 20 20 0 0 1 20 -20zm-60.148 16c-2.1339 0-3.8516 1.7177-3.8516 3.8516v0.29688c0 2.1339 1.7177 3.8516 3.8516 3.8516h12.297c2.1339 0 3.8516-1.7177 3.8516-3.8516v-0.29688c0-2.1339-1.7177-3.8516-3.8516-3.8516h-12.297zm18.902 23.951c-0.73947-0.051693-1.5023 0.10966-2.1953 0.50977l-10.648 6.1484c-1.848 1.0669-2.4771 3.4137-1.4102 5.2617l0.14844 0.25781c1.0669 1.848 3.4137 2.4771 5.2617 1.4102l10.648-6.1484c1.848-1.0669 2.4771-3.4137 1.4102-5.2617l-0.14844-0.25781c-0.66684-1.155-1.834-1.8338-3.0664-1.9199zm33.246 32.049v8h16v-8h-16z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#f7f5cf" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gizmo_particles.svg b/editor/icons/icon_gizmo_particles.svg
new file mode 100644
index 0000000000..05fc84619e
--- /dev/null
+++ b/editor/icons/icon_gizmo_particles.svg
@@ -0,0 +1,5 @@
+<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -924.36)">
+<path transform="translate(0 924.36)" d="m64 8a36 40 0 0 0 -35.311 32.256 24 24 0 0 0 -20.689 23.744 24 24 0 0 0 24 24h64a24 24 0 0 0 24 -24 24 24 0 0 0 -20.715 -23.746 36 40 0 0 0 -35.285 -32.254zm-32 88a8 8 0 0 0 -8 8 8 8 0 0 0 8 8 8 8 0 0 0 8 -8 8 8 0 0 0 -8 -8zm64 0a8 8 0 0 0 -8 8 8 8 0 0 0 8 8 8 8 0 0 0 8 -8 8 8 0 0 0 -8 -8zm-32 8a8 8 0 0 0 -8 8 8 8 0 0 0 8 8 8 8 0 0 0 8 -8 8 8 0 0 0 -8 -8z" fill="#f7f5cf"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gizmo_reflection_probe.svg b/editor/icons/icon_gizmo_reflection_probe.svg
new file mode 100644
index 0000000000..6d80e73b8c
--- /dev/null
+++ b/editor/icons/icon_gizmo_reflection_probe.svg
@@ -0,0 +1,5 @@
+<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -924.36)">
+<path transform="translate(0 924.36)" d="m12 8a4.0004 4.0004 0 0 0 -4 4v24h8v-20h96v8h8v-12a4.0004 4.0004 0 0 0 -4 -4h-104zm76 28a4 4 0 0 0 -4 4 4 4 0 0 0 4 4h18.732l-42.957 50.119-44.947-44.947-5.6562 5.6582 48 48a4.0004 4.0004 0 0 0 5.8652 -0.22656l44.963-52.457v17.854a4 4 0 0 0 4 4 4 4 0 0 0 4 -4v-28a4.0004 4.0004 0 0 0 -4 -4h-28zm-80 52v28a4.0004 4.0004 0 0 0 4 4h104a4.0004 4.0004 0 0 0 4 -4v-28h-8v24h-96v-24h-8z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#f7f5cf" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gizmo_spatial_sample_player.svg b/editor/icons/icon_gizmo_spatial_sample_player.svg
index d40fe230ac..7dbb4744be 100644
--- a/editor/icons/icon_gizmo_spatial_sample_player.svg
+++ b/editor/icons/icon_gizmo_spatial_sample_player.svg
@@ -1,5 +1,5 @@
<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m63.883 12.004a4.0004 4.0004 0 0 0 -2.7109 1.168l-30.828 30.83h-14.344a4.0004 4.0004 0 0 0 -4 4v32a4.0004 4.0004 0 0 0 4 4h14.344l30.828 30.828a4.0004 4.0004 0 0 0 6.8281 -2.8281v-96.002a4.0004 4.0004 0 0 0 -4.1172 -3.9961zm46.117 5.9961a6 6 0 0 0 -6 6v80a6 6 0 0 0 6 6 6 6 0 0 0 6 -6v-80a6 6 0 0 0 -6 -6zm-24 24a6 6 0 0 0 -6 6v32h0.34961a6 6 0 0 0 5.6504 4 6 6 0 0 0 5.6484 -4h0.35156v-32a6 6 0 0 0 -6 -6z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#f7f5cf" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path transform="translate(0 924.36)" d="m63.883 12.004c-1.0195 0.0295-1.9892 0.4473-2.7109 1.168l-30.828 30.83h-14.344c-2.209 2.21e-4 -3.9998 1.791-4 4v32c2.21e-4 2.209 1.791 3.9998 4 4h14.344l30.828 30.828c2.52 2.5182 6.8267 0.73442 6.8281-2.8281v-96.002c-0.0015-2.2541-1.8641-4.0619-4.1172-3.9961zm48.117 3.9961a4 4 0 0 0 -4 4v88a4 4 0 0 0 4 4 4 4 0 0 0 4 -4v-88a4 4 0 0 0 -4 -4zm-24 24a4 4 0 0 0 -4 4v40a4 4 0 0 0 4 4 4 4 0 0 0 4 -4v-40a4 4 0 0 0 -4 -4z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#f7f5cf" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_gizmo_spot_light.svg b/editor/icons/icon_gizmo_spot_light.svg
new file mode 100644
index 0000000000..9b4ddadd17
--- /dev/null
+++ b/editor/icons/icon_gizmo_spot_light.svg
@@ -0,0 +1,5 @@
+<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -924.36)">
+<path transform="translate(0 924.36)" d="m52 8c-4.432 0-8 3.568-8 8v12 16.875a40 36 0 0 0 -20 31.125h28a12 12 0 0 0 12 12 12 12 0 0 0 12 -12h28a40 36 0 0 0 -20 -31.141v-20.859-8c0-4.432-3.568-8-8-8h-24zm-11.969 78.006c-0.76793-0.053681-1.5596 0.1138-2.2793 0.5293l-10.393 6c-1.9191 1.108-2.5728 3.5457-1.4648 5.4648s3.5457 2.5728 5.4648 1.4648l10.393-6c1.9191-1.108 2.5709-3.5457 1.4629-5.4648-0.6925-1.1994-1.9037-1.9047-3.1836-1.9941zm47.938 0c-1.2799 0.08947-2.4911 0.7947-3.1836 1.9941-1.108 1.9191-0.45622 4.3568 1.4629 5.4648l10.393 6c1.9191 1.108 4.3568 0.45427 5.4648-1.4648s0.45427-4.3568-1.4648-5.4648l-10.393-6c-0.71967-0.4155-1.5114-0.58298-2.2793-0.5293zm-23.969 13.994c-2.216 0-4 1.784-4 4v12c0 2.216 1.784 4 4 4s4-1.784 4-4v-12c0-2.216-1.784-4-4-4z" fill="#f7f5cf" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.1082"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gui_close_dark.svg b/editor/icons/icon_gui_close_dark.svg
deleted file mode 100644
index e511a5d74a..0000000000
--- a/editor/icons/icon_gui_close_dark.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3.7578 2.3438l-1.4141 1.4141 4.2422 4.2422-4.2422 4.2422 1.4141 1.4141 4.2422-4.2422 4.2422 4.2422 1.4141-1.4141-4.2422-4.2422 4.2422-4.2422-1.4141-1.4141-4.2422 4.2422-4.2422-4.2422z" fill-opacity=".89804"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_gui_close_light.svg b/editor/icons/icon_gui_close_light.svg
deleted file mode 100644
index ac023b7030..0000000000
--- a/editor/icons/icon_gui_close_light.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3.7578 2.3438l-1.4141 1.4141 4.2422 4.2422-4.2422 4.2422 1.4141 1.4141 4.2422-4.2422 4.2422 4.2422 1.4141-1.4141-4.2422-4.2422 4.2422-4.2422-1.4141-1.4141-4.2422 4.2422-4.2422-4.2422z" fill="#fff" fill-opacity=".89804"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_move_down.svg b/editor/icons/icon_move_down.svg
index 28d0d161d8..466fa10205 100644
--- a/editor/icons/icon_move_down.svg
+++ b/editor/icons/icon_move_down.svg
@@ -1,6 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-opacity=".99608" stroke-width="2">
-<path d="m4 1045.3 4 5 4-5" stroke-linejoin="round"/>
-<path d="m8 1038.3v11"/>
+<g transform="translate(0 -1036.4)">
+<path d="m7.9964 1051.4a1.0002 1.0001 0 0 1 -0.77738 -0.377l-4.0002-5a1.0001 1 0 0 1 0.15626 -1.4043 1.0001 1 0 0 1 1.4063 0.1563l2.2189 2.7734v-5.1484a1.0001 1 0 0 1 1.0001 -1 1.0001 1 0 0 1 1.0001 1v5.1484l2.2189-2.7734a1.0001 1 0 0 1 1.4063 -0.1563 1.0001 1 0 0 1 0.15626 1.4043l-4.0002 5a1.0002 1.0001 0 0 1 -0.7852 0.377zm0.00391-12a1.0001 1 0 0 1 -1.0001 -1 1.0001 1 0 0 1 1.0001 -1 1.0001 1 0 0 1 1.0001 1 1.0001 1 0 0 1 -1.0001 1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_move_up.svg b/editor/icons/icon_move_up.svg
index cd61e66ee7..6e148216d2 100644
--- a/editor/icons/icon_move_up.svg
+++ b/editor/icons/icon_move_up.svg
@@ -1,6 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-opacity=".99608" stroke-width="2">
-<path d="m4 1043.4 4-5 4 5" stroke-linejoin="round"/>
-<path d="m8 1050.4v-11"/>
+<g transform="translate(0 -1036.4)">
+<path d="m7.9964 1037.4a1.0002 1.0001 0 0 0 -0.77739 0.377l-4.0002 5a1.0001 1 0 0 0 0.15626 1.4043 1.0001 1 0 0 0 1.4063 -0.1563l2.2189-2.7734v5.1484a1.0001 1 0 0 0 1.0001 1 1.0001 1 0 0 0 1.0001 -1v-5.1484l2.2189 2.7734a1.0001 1 0 0 0 1.4063 0.1563 1.0001 1 0 0 0 0.15626 -1.4043l-4.0002-5a1.0002 1.0001 0 0 0 -0.7852 -0.377zm0.00391 12a1.0001 1 0 0 0 -1.0001 1 1.0001 1 0 0 0 1.0001 1 1.0001 1 0 0 0 1.0001 -1 1.0001 1 0 0 0 -1.0001 -1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_multi_mesh.svg b/editor/icons/icon_multi_mesh.svg
index 09fcd9a1a8..2582ba9e51 100644
--- a/editor/icons/icon_multi_mesh.svg
+++ b/editor/icons/icon_multi_mesh.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h1.2695v-1-1h-1.2715a2 2 0 0 0 -0.72852 -0.73047v-5.8555l3.5859 3.5859h1.4141v-1-0.41406l-3.5859-3.5859h5.8574a2 2 0 0 0 0.72852 0.72656v1.2734h2v-1.2695a2 2 0 0 0 1 -1.7305 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm8 7v1.5859 1.4141h-1.4141-1.5859v1 1h3v1 2h2v-1-2h2 1v-2h-2-1v-3h-1-1z" fill="#ffd684"/>
+<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h1.2695v-2h-1.2715c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c0.17532 0.30158 0.42647 0.55205 0.72852 0.72656v1.2734h2v-1.2695c0.61831-0.35698 0.99944-1.0165 1-1.7305 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#ffd684"/>
</g>
</svg>
diff --git a/editor/icons/icon_multi_mesh_instance.svg b/editor/icons/icon_multi_mesh_instance.svg
index edade9469d..0140f1137b 100644
--- a/editor/icons/icon_multi_mesh_instance.svg
+++ b/editor/icons/icon_multi_mesh_instance.svg
@@ -1,6 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#fc9c9c" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h1.2695v-1-1h-1.2715a2 2 0 0 0 -0.72852 -0.73047v-5.8555l3.5859 3.5859h1.4141v-1-0.41406l-3.5859-3.5859h5.8574a2 2 0 0 0 0.72852 0.72656v1.2734h2v-1.2695a2 2 0 0 0 1 -1.7305 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 7v2.5859l-1-1v1.4141h-1.4141l1 1h-2.5859v1h1 2v1h0.27148a2 2 0 0 0 1.7285 1v-2h2a2 2 0 0 0 -1.0312 -1.75h0.03125v-0.25h-1v-3h-1z"/>
-<path d="m11 1044.4v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h1.2695v-2h-1.2715c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c0.17532 0.30158 0.42647 0.55205 0.72852 0.72656v1.2734h2v-1.2695c0.61831-0.35698 0.99944-1.0165 1-1.7305 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fc9c9c" fill-opacity=".99608"/>
</g>
</svg>
diff --git a/editor/icons/icon_navigation_mesh_instance.svg b/editor/icons/icon_navigation_mesh_instance.svg
index 909dbe458f..85c6292290 100644
--- a/editor/icons/icon_navigation_mesh_instance.svg
+++ b/editor/icons/icon_navigation_mesh_instance.svg
@@ -1,7 +1,6 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)" fill="#fc9c9c" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1z"/>
-<path d="m15 1051.4-3-8-3 8 3-2z" fill-rule="evenodd"/>
+<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 6l-3 8 3-2 3 2-3-8z"/>
<rect x="12" y="1040.4" width="2" height="1"/>
<rect x="12" y="1040.4" width="2" height="1"/>
</g>
diff --git a/editor/icons/icon_packed_data_container.svg b/editor/icons/icon_packed_data_container.svg
index ea347ffe38..dd5aeafb86 100644
--- a/editor/icons/icon_packed_data_container.svg
+++ b/editor/icons/icon_packed_data_container.svg
@@ -1,13 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path d="m2 1038.4v12h12v-12z" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2"/>
-<rect x="4" y="1040.4" width="2" height="2" fill="#e0e0e0"/>
-<rect x="4" y="1043.4" width="2" height="2" fill="#e0e0e0"/>
-<rect x="4" y="1046.4" width="2" height="2" fill="#e0e0e0"/>
-<rect x="7" y="1040.4" width="2" height="2" fill="#e0e0e0"/>
-<rect x="7" y="1043.4" width="2" height="2" fill="#e0e0e0"/>
-<rect x="7" y="1046.4" width="2" height="2" fill="#e0e0e0"/>
-<rect x="10" y="1040.4" width="2" height="2" fill="#e0e0e0"/>
-<rect x="10" y="1043.4" width="2" height="2" fill="#e0e0e0"/>
+<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1 -1v-12a1.0001 1.0001 0 0 0 -1 -1h-12zm1 2h10v10h-10v-10zm1 1v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-6 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-6 3v2h2v-2h-2zm3 0v2h2v-2h-2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_particle_attractor_2d.svg b/editor/icons/icon_particle_attractor_2d.svg
index c89742be04..1374304af0 100644
--- a/editor/icons/icon_particle_attractor_2d.svg
+++ b/editor/icons/icon_particle_attractor_2d.svg
@@ -1,9 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#a5b7f3" fill-opacity=".98824">
-<path transform="translate(0 1036.4)" d="m8 1a3 7 0 0 0 -3 7 3 7 0 0 0 3 7 3 7 0 0 0 3 -7 3 7 0 0 0 -3 -7zm0 1a2 6 0 0 1 2 6 2 6 0 0 1 -2 6 2 6 0 0 1 -2 -6 2 6 0 0 1 2 -6z"/>
-<path d="m1 1044.4a7 3 0 0 0 7 3 7 3 0 0 0 7 -3 7 3 0 0 0 -7 -3 7 3 0 0 0 -7 3zm1 0a6 2 0 0 1 6 -2 6 2 0 0 1 6 2 6 2 0 0 1 -6 2 6 2 0 0 1 -6 -2z"/>
-<path d="m3.0503 1049.3a3 7 45 0 0 7.0711 -2.8284 3 7 45 0 0 2.8284 -7.071 3 7 45 0 0 -7.0711 2.8284 3 7 45 0 0 -2.8284 7.071zm0.70711-0.7071a2 6 45 0 1 2.8284 -5.6568 2 6 45 0 1 5.6569 -2.8284 2 6 45 0 1 -2.8284 5.6568 2 6 45 0 1 -5.6569 2.8284z"/>
-<path d="m12.95 1049.3a7 3 45 0 0 -2.8284 -7.071 7 3 45 0 0 -7.071 -2.8284 7 3 45 0 0 2.8284 7.071 7 3 45 0 0 7.071 2.8284zm-0.7071-0.7071a6 2 45 0 1 -5.6568 -2.8284 6 2 45 0 1 -2.8284 -5.6568 6 2 45 0 1 5.6568 2.8284 6 2 45 0 1 2.8284 5.6568z"/>
-<circle cx="8" cy="1044.4" r="1"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m8 1a3 7 0 0 0 -2.0801 1.9668 7 3 45 0 0 -2.8691 0.083984 7 3 45 0 0 -0.080078 2.8633 7 3 0 0 0 -1.9707 2.0859 7 3 0 0 0 1.9668 2.0801 3 7 45 0 0 0.083984 2.8691 3 7 45 0 0 2.8633 0.080078 3 7 0 0 0 2.0859 1.9707 3 7 0 0 0 2.0801 -1.9668 7 3 45 0 0 2.8691 -0.083984 7 3 45 0 0 0.080078 -2.8633 7 3 0 0 0 1.9707 -2.0859 7 3 0 0 0 -1.9668 -2.0801 3 7 45 0 0 -0.083984 -2.8691 3 7 45 0 0 -2.8633 -0.080078 3 7 0 0 0 -2.0859 -1.9707zm0 1a2 6 0 0 1 1.2598 1.3438 3 7 45 0 0 -1.2578 0.75977 7 3 45 0 0 -1.2637 -0.75781 2 6 0 0 1 1.2617 -1.3457zm-3.6348 1.5293a6 2 45 0 1 1.2344 0.28906 3 7 0 0 0 -0.35352 1.4238 7 3 0 0 0 -1.4297 0.35742 6 2 45 0 1 -0.058594 -1.8418 6 2 45 0 1 0.60742 -0.22852zm7.0762 0.0039062a2 6 45 0 1 0.80078 0.22461 2 6 45 0 1 -0.060547 1.8418 7 3 0 0 0 -1.4238 -0.35352 3 7 0 0 0 -0.35742 -1.4297 2 6 45 0 1 1.041 -0.2832zm-4.998 0.70703a6 2 45 0 1 0.74023 0.4707 3 7 45 0 0 -0.41211 0.33984 7 3 0 0 0 -0.52344 0.048828 2 6 0 0 1 0.19531 -0.85938zm3.1152 0.0019531a2 6 0 0 1 0.18945 0.85547 7 3 0 0 0 -0.5293 -0.050781 7 3 45 0 0 -0.4043 -0.33594 2 6 45 0 1 0.74414 -0.46875zm-1.5586 1.7578a6 2 0 0 1 0.82031 0.021484 6 2 45 0 1 0.59375 0.56445 6 2 45 0 1 0.56445 0.59375 2 6 0 0 1 0.021484 0.82031 2 6 0 0 1 -0.021484 0.82031 2 6 45 0 1 -0.56445 0.59375 2 6 45 0 1 -0.59375 0.56445 6 2 0 0 1 -0.82031 0.021484 6 2 0 0 1 -0.82031 -0.021484 6 2 45 0 1 -0.59375 -0.56445 6 2 45 0 1 -0.56445 -0.59375 2 6 0 0 1 -0.021484 -0.82031 2 6 0 0 1 0.021484 -0.82031 2 6 45 0 1 0.56445 -0.59375 2 6 45 0 1 0.59375 -0.56445 6 2 0 0 1 0.82031 -0.021484zm2.9004 0.24805a6 2 0 0 1 0.85938 0.19531 2 6 45 0 1 -0.4707 0.74023 7 3 45 0 0 -0.33984 -0.41211 3 7 0 0 0 -0.048828 -0.52344zm-5.8027 0.0039062a3 7 0 0 0 -0.050781 0.5293 3 7 45 0 0 -0.33594 0.4043 6 2 45 0 1 -0.46875 -0.74414 6 2 0 0 1 0.85547 -0.18945zm7.5566 0.48633a6 2 0 0 1 1.3457 1.2617 6 2 0 0 1 -1.3438 1.2598 7 3 45 0 0 -0.75977 -1.2578 3 7 45 0 0 0.75781 -1.2637zm-9.3105 0.0019532a7 3 45 0 0 0.75977 1.2578 3 7 45 0 0 -0.75781 1.2637 6 2 0 0 1 -1.3457 -1.2617 6 2 0 0 1 1.3438 -1.2598zm4.6562 0.25977a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm3.2891 1.8145a6 2 45 0 1 0.46875 0.74414 6 2 0 0 1 -0.85547 0.18945 3 7 0 0 0 0.050781 -0.5293 3 7 45 0 0 0.33594 -0.4043zm-6.5781 0.0019531a7 3 45 0 0 0.33984 0.41211 3 7 0 0 0 0.048828 0.52344 6 2 0 0 1 -0.85938 -0.19531 2 6 45 0 1 0.4707 -0.74023zm-0.89258 1.584a7 3 0 0 0 1.4238 0.35352 3 7 0 0 0 0.35742 1.4297 2 6 45 0 1 -1.8418 0.058594 2 6 45 0 1 0.060547 -1.8418zm8.3652 0a6 2 45 0 1 0.058594 1.8418 6 2 45 0 1 -1.8418 -0.060547 3 7 0 0 0 0.35352 -1.4238 7 3 0 0 0 1.4297 -0.35742zm-2.4316 0.5a2 6 0 0 1 -0.19531 0.85938 6 2 45 0 1 -0.74023 -0.4707 3 7 45 0 0 0.41211 -0.33984 7 3 0 0 0 0.52344 -0.048828zm-3.5 0.001953a7 3 0 0 0 0.5293 0.050781 7 3 45 0 0 0.4043 0.33594 2 6 45 0 1 -0.74414 0.46875 2 6 0 0 1 -0.18945 -0.85547zm1.7461 0.99414a7 3 45 0 0 1.2637 0.75781 2 6 0 0 1 -1.2617 1.3457 2 6 0 0 1 -1.2598 -1.3438 3 7 45 0 0 1.2578 -0.75977z" fill="#a5b7f3" fill-opacity=".98824"/>
</g>
</svg>
diff --git a/editor/icons/icon_particles.svg b/editor/icons/icon_particles.svg
index f8a0ec46ec..ff58d4e47a 100644
--- a/editor/icons/icon_particles.svg
+++ b/editor/icons/icon_particles.svg
@@ -1,11 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#fc9c9c" fill-opacity=".99608">
-<circle cx="4" cy="1044.4" r="3"/>
-<ellipse cx="8" cy="1042.4" rx="4.5" ry="5"/>
-<path d="m4 1047.4h8v-4h-8z" fill-rule="evenodd"/>
-<circle cx="12" cy="1044.4" r="3"/>
-<circle cx="4" cy="1049.4" r="1"/>
-<circle cx="12" cy="1049.4" r="1"/>
-<circle cx="8" cy="1050.4" r="1"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3 -3 3 3 0 0 0 -2.5898 -2.9668 4.5 5 0 0 0 -4.4102 -4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1z" fill="#fc9c9c" fill-opacity=".99608"/>
</g>
</svg>
diff --git a/editor/icons/icon_reflection_probe.svg b/editor/icons/icon_reflection_probe.svg
index ab4ce54802..0a7f537737 100644
--- a/editor/icons/icon_reflection_probe.svg
+++ b/editor/icons/icon_reflection_probe.svg
@@ -1,5 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-6 3a1.0001 1.0001 0 0 0 -0.55273 0.89453v6a1.0001 1.0001 0 0 0 0.55273 0.89453l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1.0001 1.0001 0 0 0 0.55273 -0.89453v-6a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-6-3a1.0001 1.0001 0 0 0 -0.48438 -0.10352zm-0.96289 2.6172v8.7637l-4-2v-4.7637l4-2zm2 0l4 2v4.7637l-4 2v-8.7637z" color="#000000" color-rendering="auto" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
+<g transform="translate(0 -1036.4)" fill="none" stroke="#fc9c9c" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2">
+<path d="m2 1045.4v5h12v-4"/>
+<path d="m2 1040.4 5 6 7-7"/>
+<path d="m14 1043.4v-4h-4" stroke-linecap="round"/>
</g>
</svg>
diff --git a/editor/icons/icon_sprite_frames.svg b/editor/icons/icon_sprite_frames.svg
index 5147ccdb1e..e797819892 100644
--- a/editor/icons/icon_sprite_frames.svg
+++ b/editor/icons/icon_sprite_frames.svg
@@ -1,11 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#e0e0e0">
-<rect x="10" y="1046.4" width="2" height="2"/>
-<rect x="13" y="1046.4" width="2" height="2"/>
-<rect x="10" y="1049.4" width="2" height="2"/>
-<rect x="13" y="1049.4" width="2" height="2"/>
-<path transform="translate(0 1036.4)" d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5 -5 5 5 0 0 0 -5 -5zm-3 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-1.0039 2.4922a0.50005 0.50005 0 0 1 0.35742 0.86133c-0.61785 0.6179-1.4924 0.89648-2.3535 0.89648s-1.7357-0.27858-2.3535-0.89648a0.50005 0.50005 0 0 1 0.34766 -0.85742 0.50005 0.50005 0 0 1 0.35938 0.15039c0.38215 0.3822 1.0076 0.60352 1.6465 0.60352s1.2643-0.22132 1.6465-0.60352a0.50005 0.50005 0 0 1 0.34961 -0.1543z"/>
-<rect x="13" y="1043.4" width="2" height="2"/>
-<rect x="7" y="1049.4" width="2" height="2"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5 -5 5 5 0 0 0 -5 -5zm-3 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 2v2h2v-2h-2zm-5.0039 0.49219a0.50005 0.50005 0 0 1 0.35742 0.86133c-0.61785 0.6179-1.4924 0.89648-2.3535 0.89648s-1.7357-0.27858-2.3535-0.89648a0.50005 0.50005 0 0 1 0.34766 -0.85742 0.50005 0.50005 0 0 1 0.35938 0.15039c0.38215 0.3822 1.0076 0.60352 1.6465 0.60352s1.2643-0.22132 1.6465-0.60352a0.50005 0.50005 0 0 1 0.34961 -0.1543zm2.0039 2.5078v2h2v-2h-2zm3 0v2h2v-2h-2zm-6 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#e0e0e0"/>
</g>
</svg>
diff --git a/editor/icons/icon_tile_set.svg b/editor/icons/icon_tile_set.svg
index c7be24ae62..935afea397 100644
--- a/editor/icons/icon_tile_set.svg
+++ b/editor/icons/icon_tile_set.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2zm-12 3v2h2v-2h-2zm3 0v2h2v-2h-2zm5 1v1 5 1h5c0.55228 0 1-0.44772 1-1v-5c0-0.55228-0.44772-1-1-1v4l-1-1-1 1v-4h-3zm-8 2v2h2v-2h-2zm3 0v2h2v-2h-2zm-3 3v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#e0e0e0"/>
+<path transform="translate(0 1036.4)" d="m1 1v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm5 1v7h5c0.55228 0 1-0.44772 1-1v-5c0-0.55228-0.44772-1-1-1v4l-1-1-1 1v-4zm-8 2v2h2v-2zm3 0v2h2v-2zm-3 3v2h2v-2zm3 0v2h2v-2z" fill="#e0e0e0"/>
</g>
</svg>
diff --git a/editor/icons/icon_tool_button.svg b/editor/icons/icon_tool_button.svg
index 25bc83e690..4f0c3797f8 100644
--- a/editor/icons/icon_tool_button.svg
+++ b/editor/icons/icon_tool_button.svg
@@ -1,11 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<rect x="2" y="1047.4" width="6" height="4" ry="1.5" fill="#a5efac"/>
-<rect x="1" y="1049.4" width="8" height="2" ry="0" fill="#a5efac"/>
-<path d="m2 1042.4 3 2 3-2" fill="none" stroke="#a5efac" stroke-linejoin="round" stroke-width="2"/>
-<path d="m5 1039.4v5" fill="none" stroke="#a5efac" stroke-width="2"/>
-<g transform="translate(9,-1)" fill="#a5efac">
-<path d="m2 1038.5c-1.1979 0.4235-1.999 1.5557-2 2.8262 9.552e-4 1.2705 0.80214 2.4027 2 2.8262v7.1738c0 0.554 0.446 1 1 1s1-0.446 1-1v-7.1758c1.1972-0.4232 1.9982-1.5544 2-2.8242-0.00178-1.2698-0.80282-2.401-2-2.8242v2.8242c0 0.5523-0.44772 1-1 1s-1-0.4477-1-1z" fill="#a5efac"/>
-</g>
+<path transform="translate(0 1036.4)" d="m11 1.1738c-1.1979 0.4235-1.999 1.5557-2 2.8262 9.552e-4 1.2705 0.80214 2.4027 2 2.8262v7.1738c0 0.554 0.446 1 1 1s1-0.446 1-1v-7.1758c1.1972-0.4232 1.9982-1.5544 2-2.8242-0.0018-1.2698-0.80282-2.401-2-2.8242v2.8242c0 0.5523-0.44772 1-1 1s-1-0.4477-1-1zm-7 1.8262v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.22389 0.77347 0.22389 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328zm-0.5 8c-0.831 0-1.5 0.669-1.5 1.5v0.5h-1v2h8v-2h-1v-0.5c0-0.831-0.669-1.5-1.5-1.5z" fill="#a5efac"/>
</g>
</svg>
diff --git a/editor/icons/icon_transpose.svg b/editor/icons/icon_transpose.svg
index d92b37a7b1..7dd194d724 100644
--- a/editor/icons/icon_transpose.svg
+++ b/editor/icons/icon_transpose.svg
@@ -1,12 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#e0e0e0">
-<rect x="1" y="1037.4" width="2" height="14"/>
-<rect x="1" y="1037.4" width="14" height="2"/>
-<rect x="1" y="1049.4" width="7" height="2"/>
-<rect x="6" y="1037.4" width="2" height="14"/>
-<rect x="1" y="1042.4" width="14" height="2"/>
-<rect transform="rotate(90)" x="1037.4" y="-15" width="7" height="2"/>
-<path d="m15 1051.4h-5l5-5z" fill-rule="evenodd"/>
-<rect x="8" y="1039.4" width="5" height="3"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m1 1v14h7v-7h7v-7zm2 2h3v3h-3zm0 5h3v5h-3zm12 2-5 5h5z" fill="#e0e0e0"/>
</g>
</svg>
diff --git a/editor/icons/icon_tree.svg b/editor/icons/icon_tree.svg
index 093f9d2fc5..62efb9f94f 100644
--- a/editor/icons/icon_tree.svg
+++ b/editor/icons/icon_tree.svg
@@ -1,13 +1,6 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<rect x="20" y="1042.4" width="1" height="1" fill="#fefeff"/>
<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<rect x="1" y="1037.4" width="14" height="2" fill="#a5efac"/>
-<rect x="6" y="1041.4" width="9" height="2" fill="#a5efac"/>
-<rect x="7" y="1045.4" width="8" height="2" fill="#a5efac"/>
-<rect x="7" y="1049.4" width="8" height="2" fill="#a5efac"/>
-<path d="m2 1038.4v4h4" fill="none" stroke="#a5efac" stroke-linejoin="round" stroke-width="2"/>
-<path d="m6 1042.4v4h3" fill="none" stroke="#a5efac" stroke-linejoin="round" stroke-width="2"/>
-<path d="m2 1040.4v10h7" fill="none" stroke="#a5efac" stroke-linejoin="round" stroke-width="2"/>
+<path transform="translate(0 1036.4)" d="m1 1v13c5.52e-5 0.55226 0.44774 0.99994 1 1h13v-2h-12v-6h2v3c5.52e-5 0.55226 0.44774 0.99994 1 1h9v-2h-8v-2h8v-2h-12v-2h12v-2z" fill="#a5efac"/>
</g>
</svg>
diff --git a/editor/icons/icon_v_slider.svg b/editor/icons/icon_v_slider.svg
index c016ebd814..2da5fc8dcd 100644
--- a/editor/icons/icon_v_slider.svg
+++ b/editor/icons/icon_v_slider.svg
@@ -1,10 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path d="m6 1050.4a1.0001 1.0001 0 1 1 -2 0v-2.1308a4 4 0 0 0 1 0.1308 4 4 0 0 0 1 -0.1328zm0-9.8691a4 4 0 0 0 -1 -0.1309 4 4 0 0 0 -1 0.1329v-2.1329a1.0001 1.0001 0 1 1 2 0z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#a5efac" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-<circle transform="matrix(0,-1,-1,0,0,0)" cx="-1039.4" cy="-5" r="2" fill="#a5efac"/>
-<path d="m12 1038.4h-2" fill="none" stroke="#a5efac" stroke-linecap="round" stroke-width="2"/>
-<path d="m11 1044.4v0" fill="none" stroke="#a5efac" stroke-linecap="round" stroke-width="2"/>
-<path d="m12 1050.4h-2" fill="none" stroke="#a5efac" stroke-linecap="round" stroke-width="2"/>
-<path d="m6 1049.4h-2v-6.1308a4 4 0 0 0 1 0.1308 4 4 0 0 0 1 -0.1328z" fill="#a5efac"/>
+<path transform="translate(0 1036.4)" d="m5.0156 0.98633a1.0001 1.0001 0 0 0 -0.25977 0.029297 2 2 0 0 0 -1.7559 1.9844 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -1.7539 -1.9824 1.0001 1.0001 0 0 0 -0.23047 -0.03125zm4.9844 0.013672a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h2a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-2zm-4 5.8672a4 4 0 0 1 -1 0.13281 4 4 0 0 1 -1 -0.13086v5 1.1309 1a1.0001 1.0001 0 1 0 2 0v-1-1.1328-5zm5 0.13281a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm-1 6a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h2a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#a5efac" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_v_split_container.svg b/editor/icons/icon_v_split_container.svg
index d038edccc9..3f47d9cade 100644
--- a/editor/icons/icon_v_split_container.svg
+++ b/editor/icons/icon_v_split_container.svg
@@ -1,8 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#a5efac">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z"/>
-<rect transform="rotate(90)" x="1043.4" y="-13" width="2" height="10"/>
-<path d="m10 1045.4h-4l2 2z"/>
-<path d="m10 1043.4-2-2-2 2z"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v4h-3l-2-2-2 2h-3v-4zm0 6h3l2 2 2-2h3v4h-10v-4z" fill="#a5efac"/>
</g>
</svg>
diff --git a/editor/icons/icon_vehicle_body.svg b/editor/icons/icon_vehicle_body.svg
index 6761355d0e..01eb1798eb 100644
--- a/editor/icons/icon_vehicle_body.svg
+++ b/editor/icons/icon_vehicle_body.svg
@@ -1,7 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#fc9c9c" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m5 3a1 1 0 0 0 -1 1l-1 3h-2v4h1.0508c0.23167-1.1411 1.2398-2 2.4492-2s2.2175 0.85893 2.4492 2h2.1016c0.23167-1.1411 1.2398-2 2.4492-2s2.2175 0.85893 2.4492 2h1.0508v-4h-4v-4h-6zm1 1h4v3h-4v-3z"/>
-<circle cx="4.5" cy="1047.9" r="1.5"/>
-<circle cx="11.5" cy="1047.9" r="1.5"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m5 3a1 1 0 0 0 -1 1l-1 3h-2v4h1.0508c0.23167-1.1411 1.2398-2 2.4492-2s2.2175 0.85893 2.4492 2h2.1016c0.23167-1.1411 1.2398-2 2.4492-2s2.2175 0.85893 2.4492 2h1.0508v-4h-4v-4h-6zm1 1h4v3h-4v-3zm-1.5 6a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm7 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5z" fill="#fc9c9c" fill-opacity=".99608"/>
</g>
</svg>
diff --git a/editor/icons/icon_viewport_sprite.svg b/editor/icons/icon_viewport_sprite.svg
index 2c8c356102..4b8bbeaeba 100644
--- a/editor/icons/icon_viewport_sprite.svg
+++ b/editor/icons/icon_viewport_sprite.svg
@@ -2,9 +2,6 @@
<g transform="translate(0 -1036.4)">
<rect x="20" y="1042.4" width="1" height="1" fill="#fefeff"/>
<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<path transform="translate(0 1036.4)" d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v8c8.03e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h10c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v8c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-8c9.6e-6 -0.55228 0.44772-0.99999 1-1z" fill="#a5b7f3" fill-opacity=".98824"/>
-<rect x="4" y="1042.4" width="2" height="2" fill="#a5b7f3" fill-opacity=".98824"/>
-<rect x="10" y="1042.4" width="2" height="2" fill="#a5b7f3" fill-opacity=".98824"/>
-<rect x="4" y="1045.4" width="8" height="1" fill="#a5b7f3" fill-opacity=".98824"/>
+<path transform="translate(0 1036.4)" d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v8c8.03e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h10c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2h-10zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v8c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-8c9.6e-6 -0.55228 0.44772-0.99999 1-1zm1 3v2h2v-2h-2zm6 0v2h2v-2h-2zm-6 3v1h8v-1h-8z" fill="#a5b7f3" fill-opacity=".98824"/>
</g>
</svg>
diff --git a/editor/icons/icon_visibility_enabler.svg b/editor/icons/icon_visibility_enabler.svg
index 3aa4c6d73f..868437108a 100644
--- a/editor/icons/icon_visibility_enabler.svg
+++ b/editor/icons/icon_visibility_enabler.svg
@@ -1,9 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#fc9c9c" fill-opacity=".99608">
-<g transform="translate(-.00015202)">
-<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle cx="8" cy="1044.4" r="2"/>
-</g>
-<path transform="translate(0 1036.4)" d="m1 1v3h1v-2h2v-1h-3zm11 0v1h2v2h1v-3h-3zm-11 11v3h3v-1h-2v-2h-1zm13 0v2h-2v1h3v-3h-1z"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m1 1v3h1v-2h2v-1h-3zm11 0v1h2v2h1v-3h-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-7 6v3h3v-1h-2v-2h-1zm13 0v2h-2v1h3v-3h-1z" color="#000000" color-rendering="auto" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_visibility_enabler_2d.svg b/editor/icons/icon_visibility_enabler_2d.svg
index 15b54c0ba0..1cde98da61 100644
--- a/editor/icons/icon_visibility_enabler_2d.svg
+++ b/editor/icons/icon_visibility_enabler_2d.svg
@@ -1,9 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#a5b7f3" fill-opacity=".98824">
-<g transform="translate(-.00015202)">
-<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle cx="8" cy="1044.4" r="2"/>
-</g>
-<path transform="translate(0 1036.4)" d="m1 1v3h1v-2h2v-1h-3zm11 0v1h2v2h1v-3h-3zm-11 11v3h3v-1h-2v-2h-1zm13 0v2h-2v1h3v-3h-1z"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m1 1v3h1v-2h2v-1h-3zm11 0v1h2v2h1v-3h-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-7 6v3h3v-1h-2v-2h-1zm13 0v2h-2v1h3v-3h-1z" color="#000000" color-rendering="auto" fill="#a5b7f3" fill-opacity=".98824" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_visibility_notifier.svg b/editor/icons/icon_visibility_notifier.svg
index 807d03869c..2a631f9216 100644
--- a/editor/icons/icon_visibility_notifier.svg
+++ b/editor/icons/icon_visibility_notifier.svg
@@ -1,7 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#fc9c9c" fill-opacity=".99608">
-<path transform="translate(0 1036.4)" d="m8 3c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-0.65207 4.7109-2h-0.71094-2v-0.54102a4 4 0 0 1 -2 0.54102 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4 4 4 0 0 1 2 0.54102v-2.1816c-0.68312-0.23834-1.3644-0.35938-2-0.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<rect x="12" y="1037.4" width="2" height="6"/>
-<rect transform="scale(1,-1)" x="12" y="-1047.4" width="2" height="2"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m12 1v6h2v-6h-2zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-0.65207 4.7109-2h-0.71094-2v-0.54102a4 4 0 0 1 -2 0.54102 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4 4 4 0 0 1 2 0.54102v-2.1816c-0.68312-0.23834-1.3644-0.35938-2-0.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm4 2v2h2v-2h-2z" color="#000000" color-rendering="auto" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_visible.svg b/editor/icons/icon_visible.svg
index faa0eabb03..7d157d7b7f 100644
--- a/editor/icons/icon_visible.svg
+++ b/editor/icons/icon_visible.svg
@@ -1,6 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#e0e0e0">
-<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4z" color="#000000" color-rendering="auto" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
-<circle cx="8" cy="1044.4" r="2"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_world_environment.svg b/editor/icons/icon_world_environment.svg
index 823c6401be..d7dbd4d73e 100644
--- a/editor/icons/icon_world_environment.svg
+++ b/editor/icons/icon_world_environment.svg
@@ -1,8 +1,6 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="none" stroke="#fc9c9c" stroke-opacity=".99608">
-<circle cx="8" cy="1044.4" r="6" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
-<path d="m2 1044.4c4.5932 1.582 8.3985 1.0627 12 0" stroke-width="1.5"/>
-<path d="m8 1038.4c-3 4-3 8 0 12" stroke-width="1.5"/>
-<path d="m8 1038.4c3 4 3 8 0 12" stroke-width="1.5"/>
+<g transform="translate(0 -1036.4)" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
+<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-1.7305 2.3125c-0.83125 1.5372-1.2685 3.1037-1.2695 4.6816-0.64057-0.11251-1.3005-0.27158-1.9766-0.47266a5 5 0 0 1 3.2461 -4.209zm3.4629 0.0039062a5 5 0 0 1 3.2383 4.1875c-0.65187 0.17448-1.3077 0.32867-1.9727 0.44922-0.00845-1.5627-0.44294-3.1141-1.2656-4.6367zm-1.7324 0.0078126c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 0.054042-0.0066161 0.10803-0.0078125 0.16211-0.96392 0.096801-1.9566 0.1103-2.9844 0.027344-0.0016335-0.063192-0.0078125-0.12632-0.0078125-0.18945 0-1.5333 0.48744-3.0828 1.5-4.6758zm4.8789 5.7578a5 5 0 0 1 -3.1484 3.6055c0.57106-1.0564 0.95277-2.1268 1.1367-3.2051 0.68204-0.10905 1.3556-0.23789 2.0117-0.40039zm-9.7461 0.033203c0.68377 0.18153 1.3555 0.33345 2.0098 0.43164 0.18781 1.0551 0.56647 2.1026 1.125 3.1367a5 5 0 0 1 -3.1348 -3.5684zm6.168 0.55469c-0.22615 0.98866-0.65424 1.9884-1.3008 3.0059-0.63811-1.0042-1.0645-1.9908-1.293-2.9668 0.89027 0.054126 1.7517 0.029377 2.5938-0.039062z" fill="#fc9c9c" fill-opacity=".99608"/>
+<path transform="translate(0 1036.4)" d="m8 1v2.3242c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 0.054042-0.0066161 0.10803-0.0078125 0.16211-0.4894 0.049148-0.98713 0.077552-1.4922 0.082031v1.4922c0.43915-0.0075968 0.87287-0.031628 1.3008-0.066406-0.22615 0.98866-0.65424 1.9884-1.3008 3.0059v2.3242a7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm1.7324 2.3164a5 5 0 0 1 3.2383 4.1875c-0.65187 0.17448-1.3077 0.32867-1.9727 0.44922-0.00845-1.5627-0.44294-3.1141-1.2656-4.6367zm3.1465 5.7656a5 5 0 0 1 -3.1484 3.6055c0.57106-1.0564 0.95277-2.1268 1.1367-3.2051 0.68204-0.10905 1.3556-0.23789 2.0117-0.40039z" fill="#a5b7f3"/>
</g>
</svg>
diff --git a/editor/icons/icon_y_sort.svg b/editor/icons/icon_y_sort.svg
index 6ad296ba54..1b48f4b8e3 100644
--- a/editor/icons/icon_y_sort.svg
+++ b/editor/icons/icon_y_sort.svg
@@ -1,8 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#a5b7f3" fill-opacity=".98824">
-<rect x="9" y="1038.4" width="6" height="2"/>
-<path d="m3 1048.4h-2l3 3 3-3h-2v-8h2l-3-3-3 3h2z"/>
-<rect x="9" y="1043.4" width="4" height="2"/>
-<rect x="9" y="1048.4" width="2" height="2"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m4 1l-3 3h2v8h-2l3 3 3-3h-2v-8h2l-3-3zm5 1v2h6v-2h-6zm0 5v2h4v-2h-4zm0 5v2h2v-2h-2z" fill="#a5b7f3" fill-opacity=".98824"/>
</g>
</svg>
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 86482dad5a..b1991d755b 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -41,6 +41,7 @@
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
#include "scene/resources/packed_scene.h"
+#include "scene/resources/surface_tool.h"
#include <iostream>
@@ -868,7 +869,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int normal_pos = (normal_src->stride ? normal_src->stride : 3) * p.indices[src + normal_ofs];
ERR_FAIL_INDEX_V(normal_pos, normal_src->array.size(), ERR_INVALID_DATA);
vertex.normal = Vector3(normal_src->array[normal_pos + 0], normal_src->array[normal_pos + 1], normal_src->array[normal_pos + 2]);
- vertex.normal.snap(Vector3(0.001, 0.001, 0.001));
if (tangent_src && binormal_src) {
@@ -991,18 +991,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
}
}
- PoolVector<int> index_array;
- index_array.resize(indices_list.size());
- PoolVector<int>::Write index_arrayw = index_array.write();
-
- int iidx = 0;
- for (List<int>::Element *F = indices_list.front(); F; F = F->next()) {
-
- index_arrayw[iidx++] = F->get();
- }
-
- index_arrayw = PoolVector<int>::Write();
-
/*****************/
/* MAKE SURFACES */
/*****************/
@@ -1011,9 +999,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
Ref<SpatialMaterial> material;
- //find material
- Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
-
{
if (p_material_map.has(p.material)) {
@@ -1031,212 +1016,73 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
}
}
- PoolVector<Vector3> final_vertex_array;
- PoolVector<Vector3> final_normal_array;
- PoolVector<float> final_tangent_array;
- PoolVector<Color> final_color_array;
- PoolVector<Vector3> final_uv_array;
- PoolVector<Vector3> final_uv2_array;
- PoolVector<int> final_bone_array;
- PoolVector<float> final_weight_array;
-
- uint32_t final_format = 0;
+ Ref<SurfaceTool> surftool;
+ surftool.instance();
+ surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
- //create format
- final_format = Mesh::ARRAY_FORMAT_VERTEX | Mesh::ARRAY_FORMAT_INDEX;
-
- if (normal_src) {
- final_format |= Mesh::ARRAY_FORMAT_NORMAL;
- if (uv_src && binormal_src && tangent_src) {
- final_format |= Mesh::ARRAY_FORMAT_TANGENT;
+ for (int k = 0; k < vertex_array.size(); k++) {
+ if (normal_src) {
+ surftool->add_normal(vertex_array[k].normal);
+ if (binormal_src && tangent_src) {
+ surftool->add_tangent(vertex_array[k].tangent);
+ }
}
- }
-
- if (color_src)
- final_format |= Mesh::ARRAY_FORMAT_COLOR;
- if (uv_src)
- final_format |= Mesh::ARRAY_FORMAT_TEX_UV;
- if (uv2_src)
- final_format |= Mesh::ARRAY_FORMAT_TEX_UV2;
-
- if (has_weights) {
- final_format |= Mesh::ARRAY_FORMAT_WEIGHTS;
- final_format |= Mesh::ARRAY_FORMAT_BONES;
- }
-
- //set arrays
-
- int vlen = vertex_array.size();
- { //vertices
-
- PoolVector<Vector3> varray;
- varray.resize(vertex_array.size());
-
- PoolVector<Vector3>::Write varrayw = varray.write();
-
- for (int k = 0; k < vlen; k++)
- varrayw[k] = vertex_array[k].vertex;
-
- varrayw = PoolVector<Vector3>::Write();
- final_vertex_array = varray;
- }
-
- if (uv_src) { //compute uv first, may be needed for computing tangent/bionrmal
- PoolVector<Vector3> uvarray;
- uvarray.resize(vertex_array.size());
- PoolVector<Vector3>::Write uvarrayw = uvarray.write();
-
- for (int k = 0; k < vlen; k++) {
- uvarrayw[k] = vertex_array[k].uv;
+ if (uv_src) {
+ surftool->add_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y));
}
-
- uvarrayw = PoolVector<Vector3>::Write();
- final_uv_array = uvarray;
- }
-
- if (uv2_src) { //compute uv first, may be needed for computing tangent/bionrmal
- PoolVector<Vector3> uv2array;
- uv2array.resize(vertex_array.size());
- PoolVector<Vector3>::Write uv2arrayw = uv2array.write();
-
- for (int k = 0; k < vlen; k++) {
- uv2arrayw[k] = vertex_array[k].uv2;
+ if (uv2_src) {
+ surftool->add_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y));
}
-
- uv2arrayw = PoolVector<Vector3>::Write();
- final_uv2_array = uv2array;
- }
-
- if (normal_src) {
- PoolVector<Vector3> narray;
- narray.resize(vertex_array.size());
- PoolVector<Vector3>::Write narrayw = narray.write();
-
- for (int k = 0; k < vlen; k++) {
- narrayw[k] = vertex_array[k].normal;
+ if (color_src) {
+ surftool->add_color(vertex_array[k].color);
}
- narrayw = PoolVector<Vector3>::Write();
- final_normal_array = narray;
-
- /*
- PoolVector<Vector3> altnaray;
- _generate_normals(index_array,final_vertex_array,altnaray);
-
- for(int i=0;i<altnaray.size();i++)
- print_line(rtos(altnaray[i].dot(final_normal_array[i])));
- */
-
- } else if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
- //generate normals (even if unused later)
-
- _generate_normals(index_array, final_vertex_array, final_normal_array);
- if (OS::get_singleton()->is_stdout_verbose())
- print_line("Collada: Triangle mesh lacks normals, so normals were generated.");
- final_format |= Mesh::ARRAY_FORMAT_NORMAL;
- }
-
- if (final_normal_array.size() && uv_src && binormal_src && tangent_src && !force_make_tangents) {
+ if (has_weights) {
+ Vector<float> weights;
+ Vector<int> bones;
+ weights.resize(VS::ARRAY_WEIGHTS_SIZE);
+ bones.resize(VS::ARRAY_WEIGHTS_SIZE);
+ //float sum=0.0;
+ for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
+ if (l < vertex_array[k].weights.size()) {
+ weights[l] = vertex_array[k].weights[l].weight;
+ bones[l] = vertex_array[k].weights[l].bone_idx;
+ //sum += vertex_array[k].weights[l].weight;
+ } else {
- PoolVector<real_t> tarray;
- tarray.resize(vertex_array.size() * 4);
- PoolVector<real_t>::Write tarrayw = tarray.write();
+ weights[l] = 0;
+ bones[l] = 0;
+ }
+ }
- for (int k = 0; k < vlen; k++) {
- tarrayw[k * 4 + 0] = vertex_array[k].tangent.normal.x;
- tarrayw[k * 4 + 1] = vertex_array[k].tangent.normal.y;
- tarrayw[k * 4 + 2] = vertex_array[k].tangent.normal.z;
- tarrayw[k * 4 + 3] = vertex_array[k].tangent.d;
+ surftool->add_bones(bones);
+ surftool->add_weights(weights);
}
- tarrayw = PoolVector<real_t>::Write();
-
- final_tangent_array = tarray;
- } else if (final_normal_array.size() && primitive == Mesh::PRIMITIVE_TRIANGLES && final_uv_array.size() && (force_make_tangents || (material.is_valid()))) {
- //if this uses triangles, there are uvs and the material is using a normalmap, generate tangents and binormals, because they WILL be needed
- //generate binormals/tangents
- _generate_tangents_and_binormals(index_array, final_vertex_array, final_uv_array, final_normal_array, final_tangent_array);
- final_format |= Mesh::ARRAY_FORMAT_TANGENT;
- if (OS::get_singleton()->is_stdout_verbose())
- print_line("Collada: Triangle mesh lacks tangents (And normalmap was used), so tangents were generated.");
+ surftool->add_vertex(vertex_array[k].vertex);
}
- if (color_src) {
- PoolVector<Color> colorarray;
- colorarray.resize(vertex_array.size());
- PoolVector<Color>::Write colorarrayw = colorarray.write();
-
- for (int k = 0; k < vlen; k++) {
- colorarrayw[k] = vertex_array[k].color;
- }
-
- colorarrayw = PoolVector<Color>::Write();
-
- final_color_array = colorarray;
+ for (List<int>::Element *E = indices_list.front(); E; E = E->next()) {
+ surftool->add_index(E->get());
}
- if (has_weights) {
- PoolVector<float> weightarray;
- PoolVector<int> bonearray;
-
- weightarray.resize(vertex_array.size() * 4);
- PoolVector<float>::Write weightarrayw = weightarray.write();
- bonearray.resize(vertex_array.size() * 4);
- PoolVector<int>::Write bonearrayw = bonearray.write();
-
- for (int k = 0; k < vlen; k++) {
- float sum = 0;
-
- for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
- if (l < vertex_array[k].weights.size()) {
- weightarrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = vertex_array[k].weights[l].weight;
- sum += weightarrayw[k * VS::ARRAY_WEIGHTS_SIZE + l];
- bonearrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = int(vertex_array[k].weights[l].bone_idx);
- //COLLADA_PRINT(itos(k)+": "+rtos(bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l])+":"+rtos(weightarray[k*VS::ARRAY_WEIGHTS_SIZE+l]));
- } else {
-
- weightarrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = 0;
- bonearrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = 0;
- }
- }
- /*
- if (sum<0.8)
- COLLADA_PRINT("ERROR SUMMING INDEX "+itos(k)+" had weights: "+itos(vertex_array[k].weights.size()));
- */
- }
+ if (!normal_src) {
+ //should always be normals
+ surftool->generate_normals();
+ }
- weightarrayw = PoolVector<float>::Write();
- bonearrayw = PoolVector<int>::Write();
+ if ((!binormal_src || !tangent_src) && normal_src && uv_src && force_make_tangents) {
- final_weight_array = weightarray;
- final_bone_array = bonearray;
+ surftool->generate_tangents();
}
////////////////////////////
// FINALLY CREATE SUFRACE //
////////////////////////////
- Array d;
+ Array d = surftool->commit_to_arrays();
d.resize(VS::ARRAY_MAX);
- d[Mesh::ARRAY_INDEX] = index_array;
- d[Mesh::ARRAY_VERTEX] = final_vertex_array;
-
- if (final_normal_array.size())
- d[Mesh::ARRAY_NORMAL] = final_normal_array;
- if (final_tangent_array.size())
- d[Mesh::ARRAY_TANGENT] = final_tangent_array;
- if (final_uv_array.size())
- d[Mesh::ARRAY_TEX_UV] = final_uv_array;
- if (final_uv2_array.size())
- d[Mesh::ARRAY_TEX_UV2] = final_uv2_array;
- if (final_color_array.size())
- d[Mesh::ARRAY_COLOR] = final_color_array;
- if (final_weight_array.size())
- d[Mesh::ARRAY_WEIGHTS] = final_weight_array;
- if (final_bone_array.size())
- d[Mesh::ARRAY_BONES] = final_bone_array;
-
Array mr;
////////////////////////////
@@ -1249,10 +1095,10 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
Array a = p_morph_meshes[mi]->surface_get_arrays(surface);
//add valid weight and bone arrays if they exist, TODO check if they are unique to shape (generally not)
- if (final_weight_array.size())
- a[Mesh::ARRAY_WEIGHTS] = final_weight_array;
- if (final_bone_array.size())
- a[Mesh::ARRAY_BONES] = final_bone_array;
+ if (has_weights) {
+ a[Mesh::ARRAY_WEIGHTS] = d[Mesh::ARRAY_WEIGHTS];
+ a[Mesh::ARRAY_BONES] = d[Mesh::ARRAY_BONES];
+ }
a[Mesh::ARRAY_INDEX] = Variant();
//a.resize(Mesh::ARRAY_MAX); //no need for index
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index 2f03e72851..21cf08f524 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -474,7 +474,7 @@ Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, int p_buffe
int buffer_end = (stride * (count - 1)) + element_size;
ERR_FAIL_COND_V(buffer_end > bv.byte_length, ERR_PARSE_ERROR);
- ERR_FAIL_COND_V((offset + buffer_end) > buffer.size(), ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V((int)(offset + buffer_end) > buffer.size(), ERR_PARSE_ERROR);
//fill everything as doubles
@@ -1434,6 +1434,8 @@ Error EditorSceneImporterGLTF::_parse_cameras(GLTFState &state) {
}
print_line("total cameras: " + itos(state.cameras.size()));
+
+ return OK;
}
Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index dd98494504..594728d2e0 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -933,13 +933,13 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), meshes_out ? 1 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), (meshes_out || materials_out) ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Built-In,Files", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_on_reimport"), materials_out ? true : false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? true : false));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), ""));
@@ -1167,7 +1167,8 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
memdelete(scene);
- EditorNode::get_singleton()->reload_scene(p_source_file);
+ //this is not the time to reimport, wait until import process is done, import file is saved, etc.
+ //EditorNode::get_singleton()->reload_scene(p_source_file);
return OK;
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index bf8d88ce0a..9c3d5e7876 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -83,9 +83,9 @@ class ResourceImporterScene : public ResourceImporter {
static ResourceImporterScene *singleton;
enum Presets {
- PRESET_SINGLE_SCENE,
PRESET_SEPARATE_MATERIALS,
PRESET_SEPARATE_MESHES,
+ PRESET_SINGLE_SCENE,
PRESET_SEPARATE_MESHES_AND_MATERIALS,
PRESET_MULTIPLE_SCENES,
PRESET_MULTIPLE_SCENES_AND_MATERIALS,
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 6de523736b..ade3550daa 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -199,7 +199,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "stream"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "detect_3d"), p_preset == PRESET_DETECT));
- r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0.001,100,0.1"), 1.0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.1"), 1.0));
}
void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal) {
@@ -357,7 +357,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1;
bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
int normal = p_options["compress/normal_map"];
- float scale = p_options["scale"];
+ float scale = p_options["svg/scale"];
Ref<Image> image;
image.instance();
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index 25185149b1..e2bacd70e4 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -129,7 +129,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
int format_freq = 0;
int loop_begin = 0;
int loop_end = 0;
- int frames;
+ int frames = 0;
Vector<float> data;
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 6662fa9f21..112e3abcb5 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "import_dock.h"
+#include "editor_node.h"
class ImportDockParameters : public Object {
GDCLASS(ImportDockParameters, Object)
@@ -264,16 +265,14 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
void ImportDock::_preset_selected(int p_idx) {
- switch (p_idx) {
- case ITEM_SET_AS_DEFAULT: {
- List<ResourceImporter::ImportOption> options;
-
- params->importer->get_import_options(&options, p_idx);
+ int item_id = preset->get_popup()->get_item_id(p_idx);
+ switch (item_id) {
+ case ITEM_SET_AS_DEFAULT: {
Dictionary d;
- for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
- d[E->get().option.name] = E->get().default_value;
+ for (const List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
+ d[E->get().name] = params->values[E->get().name];
}
ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), d);
@@ -350,6 +349,15 @@ void ImportDock::_reimport() {
EditorFileSystem::get_singleton()->emit_signal("filesystem_changed"); //it changed, so force emitting the signal
}
+void ImportDock::_notification(int p_what) {
+ switch (p_what) {
+
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+
+ imported->add_style_override("normal", get_stylebox("normal", "LineEdit"));
+ } break;
+ }
+}
void ImportDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_reimport"), &ImportDock::_reimport);
@@ -365,8 +373,8 @@ void ImportDock::initialize_import_options() const {
ImportDock::ImportDock() {
- imported = memnew(LineEdit);
- imported->set_editable(false);
+ imported = memnew(Label);
+ imported->add_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_stylebox("normal", "LineEdit"));
add_child(imported);
HBoxContainer *hb = memnew(HBoxContainer);
add_margin_child(TTR("Import As:"), hb);
diff --git a/editor/import_dock.h b/editor/import_dock.h
index afb899d9c9..029c458320 100644
--- a/editor/import_dock.h
+++ b/editor/import_dock.h
@@ -41,7 +41,7 @@ class ImportDockParameters;
class ImportDock : public VBoxContainer {
GDCLASS(ImportDock, VBoxContainer)
- LineEdit *imported;
+ Label *imported;
OptionButton *import_as;
MenuButton *preset;
PropertyEditor *import_opts;
@@ -65,6 +65,7 @@ class ImportDock : public VBoxContainer {
protected:
static void _bind_methods();
+ void _notification(int p_what);
public:
void set_edit_path(const String &p_path);
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index bfbb2dc3d3..7edaf0e5af 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -58,6 +58,9 @@ void NodeDock::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
connections_button->set_icon(get_icon("Connect", "EditorIcons"));
groups_button->set_icon(get_icon("Groups", "EditorIcons"));
+ } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ connections_button->set_icon(get_icon("Connect", "EditorIcons"));
+ groups_button->set_icon(get_icon("Groups", "EditorIcons"));
}
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 68c4d0224d..df4598793c 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -409,7 +409,7 @@ bool CanvasItemEditor::_is_part_of_subscene(CanvasItem *p_item) {
return item_owner && item_owner != scene_node && p_item != scene_node && item_owner->get_filename() != "";
}
-void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, Vector<_SelectResult> &r_items, unsigned int limit) {
+void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, Vector<_SelectResult> &r_items, int limit) {
if (!p_node)
return;
if (Object::cast_to<Viewport>(p_node))
@@ -1019,6 +1019,51 @@ void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) {
}
}
+void CanvasItemEditor::_update_cursor() {
+
+ CursorShape c = CURSOR_ARROW;
+ switch (drag) {
+ case DRAG_NONE:
+ if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
+ c = CURSOR_DRAG;
+ } else {
+ switch (tool) {
+ case TOOL_MOVE:
+ c = CURSOR_MOVE;
+ break;
+ case TOOL_EDIT_PIVOT:
+ c = CURSOR_CROSS;
+ break;
+ case TOOL_PAN:
+ c = CURSOR_DRAG;
+ break;
+ }
+ }
+ break;
+ case DRAG_LEFT:
+ case DRAG_RIGHT:
+ c = CURSOR_HSIZE;
+ break;
+ case DRAG_TOP:
+ case DRAG_BOTTOM:
+ c = CURSOR_VSIZE;
+ break;
+ case DRAG_TOP_LEFT:
+ case DRAG_BOTTOM_RIGHT:
+ c = CURSOR_FDIAGSIZE;
+ break;
+ case DRAG_TOP_RIGHT:
+ case DRAG_BOTTOM_LEFT:
+ c = CURSOR_BDIAGSIZE;
+ break;
+ case DRAG_ALL:
+ case DRAG_NODE_2D:
+ c = CURSOR_MOVE;
+ break;
+ }
+ viewport->set_default_cursor_shape(c);
+}
+
void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
{
@@ -1457,6 +1502,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
// Mouse motion event
+ _update_cursor();
if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
viewport->call_deferred("grab_focus");
@@ -1881,7 +1927,7 @@ void CanvasItemEditor::_viewport_draw() {
if (snap_show_grid) {
//Draw the grid
Size2 s = viewport->get_size();
- int last_cell;
+ int last_cell = 0;
Transform2D xform = transform.affine_inverse();
Vector2 grid_offset;
@@ -2257,17 +2303,17 @@ void CanvasItemEditor::_notification(int p_what) {
anchors[MARGIN_RIGHT] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_RIGHT);
anchors[MARGIN_TOP] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_TOP);
anchors[MARGIN_BOTTOM] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_BOTTOM);
- }
- if (r != se->prev_rect || xform != se->prev_xform || pivot != se->prev_pivot || anchors[MARGIN_LEFT] != se->prev_anchors[MARGIN_LEFT] || anchors[MARGIN_RIGHT] != se->prev_anchors[MARGIN_RIGHT] || anchors[MARGIN_TOP] != se->prev_anchors[MARGIN_TOP] || anchors[MARGIN_BOTTOM] != se->prev_anchors[MARGIN_BOTTOM]) {
- viewport->update();
- se->prev_rect = r;
- se->prev_xform = xform;
- se->prev_pivot = pivot;
- se->prev_anchors[MARGIN_LEFT] = anchors[MARGIN_LEFT];
- se->prev_anchors[MARGIN_RIGHT] = anchors[MARGIN_RIGHT];
- se->prev_anchors[MARGIN_TOP] = anchors[MARGIN_TOP];
- se->prev_anchors[MARGIN_BOTTOM] = anchors[MARGIN_BOTTOM];
+ if (r != se->prev_rect || xform != se->prev_xform || pivot != se->prev_pivot || anchors[MARGIN_LEFT] != se->prev_anchors[MARGIN_LEFT] || anchors[MARGIN_RIGHT] != se->prev_anchors[MARGIN_RIGHT] || anchors[MARGIN_TOP] != se->prev_anchors[MARGIN_TOP] || anchors[MARGIN_BOTTOM] != se->prev_anchors[MARGIN_BOTTOM]) {
+ viewport->update();
+ se->prev_rect = r;
+ se->prev_xform = xform;
+ se->prev_pivot = pivot;
+ se->prev_anchors[MARGIN_LEFT] = anchors[MARGIN_LEFT];
+ se->prev_anchors[MARGIN_RIGHT] = anchors[MARGIN_RIGHT];
+ se->prev_anchors[MARGIN_TOP] = anchors[MARGIN_TOP];
+ se->prev_anchors[MARGIN_BOTTOM] = anchors[MARGIN_BOTTOM];
+ }
}
}
@@ -2320,7 +2366,6 @@ void CanvasItemEditor::_notification(int p_what) {
ungroup_button->set_icon(get_icon("Ungroup", "EditorIcons"));
key_insert_button->set_icon(get_icon("Key", "EditorIcons"));
- //anchor_menu->add_icon_override("Align Top Left");
anchor_menu->set_icon(get_icon("Anchor", "EditorIcons"));
PopupMenu *p = anchor_menu->get_popup();
@@ -2347,6 +2392,48 @@ void CanvasItemEditor::_notification(int p_what) {
AnimationPlayerEditor::singleton->get_key_editor()->connect("visibility_changed", this, "_keying_changed");
_keying_changed();
+ } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+
+ select_sb->set_texture(get_icon("EditorRect2D", "EditorIcons"));
+
+ select_button->set_icon(get_icon("ToolSelect", "EditorIcons"));
+ list_select_button->set_icon(get_icon("ListSelect", "EditorIcons"));
+ move_button->set_icon(get_icon("ToolMove", "EditorIcons"));
+ rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons"));
+ pan_button->set_icon(get_icon("ToolPan", "EditorIcons"));
+ pivot_button->set_icon(get_icon("EditPivot", "EditorIcons"));
+ select_handle = get_icon("EditorHandle", "EditorIcons");
+ anchor_handle = get_icon("EditorControlAnchor", "EditorIcons");
+ lock_button->set_icon(get_icon("Lock", "EditorIcons"));
+ unlock_button->set_icon(get_icon("Unlock", "EditorIcons"));
+ group_button->set_icon(get_icon("Group", "EditorIcons"));
+ ungroup_button->set_icon(get_icon("Ungroup", "EditorIcons"));
+ key_insert_button->set_icon(get_icon("Key", "EditorIcons"));
+
+ anchor_menu->set_icon(get_icon("Anchor", "EditorIcons"));
+ PopupMenu *p = anchor_menu->get_popup();
+ p->clear();
+
+ p->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), "Top Left", ANCHOR_ALIGN_TOP_LEFT);
+ p->add_icon_item(get_icon("ControlAlignTopRight", "EditorIcons"), "Top Right", ANCHOR_ALIGN_TOP_RIGHT);
+ p->add_icon_item(get_icon("ControlAlignBottomRight", "EditorIcons"), "Bottom Right", ANCHOR_ALIGN_BOTTOM_RIGHT);
+ p->add_icon_item(get_icon("ControlAlignBottomLeft", "EditorIcons"), "Bottom Left", ANCHOR_ALIGN_BOTTOM_LEFT);
+ p->add_separator();
+ p->add_icon_item(get_icon("ControlAlignLeftCenter", "EditorIcons"), "Center Left", ANCHOR_ALIGN_CENTER_LEFT);
+ p->add_icon_item(get_icon("ControlAlignTopCenter", "EditorIcons"), "Center Top", ANCHOR_ALIGN_CENTER_TOP);
+ p->add_icon_item(get_icon("ControlAlignRightCenter", "EditorIcons"), "Center Right", ANCHOR_ALIGN_CENTER_RIGHT);
+ p->add_icon_item(get_icon("ControlAlignBottomCenter", "EditorIcons"), "Center Bottom", ANCHOR_ALIGN_CENTER_BOTTOM);
+ p->add_icon_item(get_icon("ControlAlignCenter", "EditorIcons"), "Center", ANCHOR_ALIGN_CENTER);
+ p->add_separator();
+ p->add_icon_item(get_icon("ControlAlignLeftWide", "EditorIcons"), "Left Wide", ANCHOR_ALIGN_LEFT_WIDE);
+ p->add_icon_item(get_icon("ControlAlignTopWide", "EditorIcons"), "Top Wide", ANCHOR_ALIGN_TOP_WIDE);
+ p->add_icon_item(get_icon("ControlAlignRightWide", "EditorIcons"), "Right Wide", ANCHOR_ALIGN_RIGHT_WIDE);
+ p->add_icon_item(get_icon("ControlAlignBottomWide", "EditorIcons"), "Bottom Wide", ANCHOR_ALIGN_BOTTOM_WIDE);
+ p->add_icon_item(get_icon("ControlVcenterWide", "EditorIcons"), "VCenter Wide ", ANCHOR_ALIGN_VCENTER_WIDE);
+ p->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHOR_ALIGN_HCENTER_WIDE);
+ p->add_separator();
+ p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHOR_ALIGN_WIDE);
+ p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect and Fit Parent", ANCHOR_ALIGN_WIDE_FIT);
}
}
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index cc5dc6d3fc..52b4a37a88 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -291,7 +291,7 @@ class CanvasItemEditor : public VBoxContainer {
int handle_len;
bool _is_part_of_subscene(CanvasItem *p_item);
- void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, Vector<_SelectResult> &r_items, unsigned int limit = 0);
+ void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, Vector<_SelectResult> &r_items, int limit = 0);
void _find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, List<CanvasItem *> *r_items);
void _select_click_on_empty_area(Point2 p_click_pos, bool p_append, bool p_box_selection);
@@ -324,6 +324,7 @@ class CanvasItemEditor : public VBoxContainer {
bool updating_scroll;
void _update_scroll(float);
void _update_scrollbars();
+ void _update_cursor();
void incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric);
void incend(float &beg, float &end, float inc, float minsize, bool p_symmetric);
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index c90462db1d..38f95d8278 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -344,6 +344,10 @@ void CollisionPolygon2DEditor::edit(Node *p_collision_polygon) {
if (p_collision_polygon) {
node = Object::cast_to<CollisionPolygon2D>(p_collision_polygon);
+ //Enable the pencil tool if the polygon is empty
+ if (node->get_polygon().size() == 0) {
+ _menu_option(MODE_CREATE);
+ }
if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
wip.clear();
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index 3ac055e650..24c4813771 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -468,6 +468,10 @@ void CollisionPolygonEditor::edit(Node *p_collision_polygon) {
if (p_collision_polygon) {
node = Object::cast_to<CollisionPolygon>(p_collision_polygon);
+ //Enable the pencil tool if the polygon is empty
+ if (node->get_polygon().size() == 0) {
+ _menu_option(MODE_CREATE);
+ }
wip.clear();
wip_active = false;
edited_point = -1;
diff --git a/editor/plugins/cube_grid_theme_editor_plugin.cpp b/editor/plugins/cube_grid_theme_editor_plugin.cpp
index 08b38c2ca2..1c17daf425 100644
--- a/editor/plugins/cube_grid_theme_editor_plugin.cpp
+++ b/editor/plugins/cube_grid_theme_editor_plugin.cpp
@@ -88,7 +88,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
if (mesh.is_null())
continue;
- int id = p_library->find_item_name(mi->get_name());
+ int id = p_library->find_item_by_name(mi->get_name());
if (id < 0) {
id = p_library->get_last_unused_item_id();
@@ -111,7 +111,8 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
sb->get_shape_owners(&shapes);
for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) {
- if (sb->is_shape_owner_disabled(E->get())) continue;
+ if (sb->is_shape_owner_disabled(E->get()))
+ continue;
//Transform shape_transform = sb->shape_owner_get_transform(E->get());
@@ -120,7 +121,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) {
Ref<Shape> collision = sb->shape_owner_get_shape(E->get(), k);
- if (collision.is_valid())
+ if (!collision.is_valid())
continue;
MeshLibrary::ShapeData shape_data;
shape_data.shape = collision;
diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index abd2559d1f..51f00e5751 100644
--- a/editor/plugins/gradient_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* color_ramp_editor_plugin.cpp */
+/* gradient_editor_plugin.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h
index c169fa0947..ff7bf858c7 100644
--- a/editor/plugins/gradient_editor_plugin.h
+++ b/editor/plugins/gradient_editor_plugin.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* color_ramp_editor_plugin.h */
+/* gradient_editor_plugin.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp
index a5f854e1b1..84620a75a5 100644
--- a/editor/plugins/line_2d_editor_plugin.cpp
+++ b/editor/plugins/line_2d_editor_plugin.cpp
@@ -211,7 +211,7 @@ void Line2DEditor::_bind_methods() {
}
void Line2DEditor::_mode_selected(int p_mode) {
- for (unsigned int i = 0; i < _MODE_COUNT; ++i) {
+ for (int i = 0; i < _MODE_COUNT; ++i) {
toolbar_buttons[i]->set_pressed(i == p_mode);
}
mode = Mode(p_mode);
diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp
index 76e969a339..de8d4f9618 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/editor/plugins/navigation_polygon_editor_plugin.cpp
@@ -69,6 +69,7 @@ void NavigationPolygonEditor::_create_nav() {
undo_redo->add_do_method(node, "set_navigation_polygon", Ref<NavigationPolygon>(memnew(NavigationPolygon)));
undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(REF()));
undo_redo->commit_action();
+ _menu_option(MODE_CREATE);
}
void NavigationPolygonEditor::_menu_option(int p_option) {
@@ -423,6 +424,11 @@ void NavigationPolygonEditor::edit(Node *p_collision_polygon) {
if (p_collision_polygon) {
node = Object::cast_to<NavigationPolygonInstance>(p_collision_polygon);
+ //Enable the pencil tool if the polygon is empty
+ if (!node->get_navigation_polygon().is_null()) {
+ if (node->get_navigation_polygon()->get_polygon_count() == 0)
+ _menu_option(MODE_CREATE);
+ }
if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
wip.clear();
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index d04184f055..f7008298f0 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -402,10 +402,13 @@ bool Polygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
cpoint = canvas_item_editor->snap_point(cpoint);
edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
- Vector<Vector2> poly = Variant(node->get_polygon());
- ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos - node->get_offset();
- node->set_polygon(Variant(poly));
+ if (!wip_active) {
+
+ Vector<Vector2> poly = Variant(node->get_polygon());
+ ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
+ poly[edited_point] = edited_point_pos - node->get_offset();
+ node->set_polygon(Variant(poly));
+ }
canvas_item_editor->get_viewport_control()->update();
}
@@ -430,7 +433,7 @@ void Polygon2DEditor::_canvas_draw() {
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
- if (edited_point >= 0 && EDITOR_DEF("editors/poly_editor/show_previous_outline", true)) {
+ if (!wip_active && edited_point >= 0 && EDITOR_DEF("editors/poly_editor/show_previous_outline", true)) {
const Color col = node->get_color().contrasted();
const int n = pre_move_edit.size();
@@ -656,7 +659,7 @@ void Polygon2DEditor::_uv_draw() {
if (snap_show_grid) {
Size2 s = uv_edit_draw->get_size();
- int last_cell;
+ int last_cell = 0;
if (snap_step.x != 0) {
for (int i = 0; i < s.width; i++) {
@@ -720,6 +723,10 @@ void Polygon2DEditor::edit(Node *p_collision_polygon) {
if (p_collision_polygon) {
node = Object::cast_to<Polygon2D>(p_collision_polygon);
+ //Enable the pencil tool if the polygon is empty
+ if (node->get_polygon().size() == 0) {
+ _menu_option(MODE_CREATE);
+ }
if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 6f35ca1b0c..04be1ba4ab 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -47,7 +47,7 @@
void ScriptEditorBase::_bind_methods() {
ADD_SIGNAL(MethodInfo("name_changed"));
- ADD_SIGNAL(MethodInfo("script_changed"));
+ ADD_SIGNAL(MethodInfo("edited_script_changed"));
ADD_SIGNAL(MethodInfo("request_help_search", PropertyInfo(Variant::STRING, "topic")));
ADD_SIGNAL(MethodInfo("request_help_index"));
ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line")));
@@ -972,6 +972,14 @@ void ScriptEditor::_menu_option(int p_option) {
EditorNode::get_singleton()->show_warning("Can't obtain the script for running");
break;
}
+
+ current->apply_code();
+ Error err = scr->reload(false); //hard reload script before running always
+
+ if (err != OK) {
+ EditorNode::get_singleton()->show_warning("Script failed reloading, check console for errors.");
+ return;
+ }
if (!scr->is_tool()) {
EditorNode::get_singleton()->show_warning("Script is not in tool mode, will not be able to run");
@@ -1149,7 +1157,12 @@ void ScriptEditor::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
+ help_search->set_icon(get_icon("HelpSearch", "EditorIcons"));
+ site_search->set_icon(get_icon("Instance", "EditorIcons"));
+ class_search->set_icon(get_icon("ClassList", "EditorIcons"));
+
+ script_forward->set_icon(get_icon("Forward", "EditorIcons"));
+ script_back->set_icon(get_icon("Back", "EditorIcons"));
} break;
default:
@@ -1410,7 +1423,7 @@ void ScriptEditor::_update_script_colors() {
int non_zero_hist_size = (hist_size == 0) ? 1 : hist_size;
float v = Math::ease((edit_pass - pass) / float(non_zero_hist_size), 0.4);
- script_list->set_item_custom_bg_color(i, hot_color.linear_interpolate(cold_color, v));
+ script_list->set_item_custom_fg_color(i, hot_color.linear_interpolate(cold_color, v));
}
}
}
@@ -1532,8 +1545,14 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change");
+ if (p_script->get_language()->overrides_external_editor()) {
+ Error err = p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col);
+ if (err != OK)
+ ERR_PRINT("Couldn't open script in the overridden external text editor");
+ return false;
+ }
+
if ((debugger->get_dump_stack_script() != p_script || debugger->get_debug_with_external_editor()) &&
- p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col) == OK &&
p_script->get_path().is_resource_file() &&
bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
@@ -1622,7 +1641,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
_update_script_names();
_save_layout();
se->connect("name_changed", this, "_update_script_names");
- se->connect("script_changed", this, "_script_changed");
+ se->connect("edited_script_changed", this, "_script_changed");
se->connect("request_help_search", this, "_help_search");
se->connect("request_open_script_at_line", this, "_goto_script_line");
se->connect("go_to_help", this, "_help_class_goto");
@@ -2160,8 +2179,8 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_current_script"), &ScriptEditor::_get_current_script);
ClassDB::bind_method(D_METHOD("get_open_scripts"), &ScriptEditor::_get_open_scripts);
- ADD_SIGNAL(MethodInfo("editor_script_changed", PropertyInfo(Variant::OBJECT, "script:Script")));
- ADD_SIGNAL(MethodInfo("script_close", PropertyInfo(Variant::OBJECT, "script:Script")));
+ ADD_SIGNAL(MethodInfo("editor_script_changed", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
+ ADD_SIGNAL(MethodInfo("script_close", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
}
ScriptEditor::ScriptEditor(EditorNode *p_editor) {
@@ -2203,7 +2222,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
members_overview->set_v_size_flags(SIZE_EXPAND_FILL);
tab_container = memnew(TabContainer);
- tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
tab_container->set_tabs_visible(false);
script_split->add_child(tab_container);
@@ -2499,9 +2517,9 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true);
EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true);
EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15);
- EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color(1, 0, 0, 0.3));
- EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(0, 0, 1, 0.3));
- EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(0.81, 0.81, 0.14, 0.63));
+ EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color::html("ed5e5e"));
+ EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(1, 1, 1, 0.3));
+ EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5));
EDITOR_DEF("text_editor/open_scripts/group_help_pages", true);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path"));
EDITOR_DEF("text_editor/open_scripts/sort_scripts_by", 0);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 89dc358d02..fae57eb5d2 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -75,14 +75,9 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->clear_colors();
- /* color from color_theme or from editor color */
-
- Color background_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0));
- if (EDITOR_DEF("text_editor/theme/adapted_code_editor_background_color", false))
- background_color = get_color("dark_color_1", "Editor");
-
/* keyword color */
- text_edit->add_color_override("background_color", background_color);
+
+ text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)));
text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0)));
text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244")));
text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf")));
@@ -120,17 +115,29 @@ void ScriptTextEditor::_load_theme_settings() {
//colorize core types
Color basetype_color = EDITOR_DEF("text_editor/highlighting/base_type_color", Color(0.3, 0.3, 0.0));
+ text_edit->add_keyword_color("String", basetype_color);
text_edit->add_keyword_color("Vector2", basetype_color);
+ text_edit->add_keyword_color("Rect2", basetype_color);
+ text_edit->add_keyword_color("Transform2D", basetype_color);
text_edit->add_keyword_color("Vector3", basetype_color);
+ text_edit->add_keyword_color("Rect3", basetype_color);
+ text_edit->add_keyword_color("Basis", basetype_color);
text_edit->add_keyword_color("Plane", basetype_color);
- text_edit->add_keyword_color("Quat", basetype_color);
- text_edit->add_keyword_color("AABB", basetype_color);
- text_edit->add_keyword_color("Matrix3", basetype_color);
text_edit->add_keyword_color("Transform", basetype_color);
+ text_edit->add_keyword_color("Quat", basetype_color);
text_edit->add_keyword_color("Color", basetype_color);
- text_edit->add_keyword_color("Image", basetype_color);
- text_edit->add_keyword_color("Rect2", basetype_color);
+ text_edit->add_keyword_color("Object", basetype_color);
text_edit->add_keyword_color("NodePath", basetype_color);
+ text_edit->add_keyword_color("RID", basetype_color);
+ text_edit->add_keyword_color("Dictionary", basetype_color);
+ text_edit->add_keyword_color("Array", basetype_color);
+ text_edit->add_keyword_color("PoolByteArray", basetype_color);
+ text_edit->add_keyword_color("PoolIntArray", basetype_color);
+ text_edit->add_keyword_color("PoolRealArray", basetype_color);
+ text_edit->add_keyword_color("PoolStringArray", basetype_color);
+ text_edit->add_keyword_color("PoolVector2Array", basetype_color);
+ text_edit->add_keyword_color("PoolVector3Array", basetype_color);
+ text_edit->add_keyword_color("PoolColorArray", basetype_color);
//colorize engine types
Color type_color = EDITOR_DEF("text_editor/highlighting/engine_type_color", Color(0.0, 0.2, 0.4));
@@ -529,7 +536,7 @@ void ScriptTextEditor::_validate_script() {
}
emit_signal("name_changed");
- emit_signal("script_changed");
+ emit_signal("edited_script_changed");
}
static Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) {
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 069a0c4292..b02016c273 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -93,9 +93,9 @@ void ShaderTextEditor::_load_theme_settings() {
if (shader.is_valid()) {
- for (const Map<StringName, Map<StringName, ShaderLanguage::DataType> >::Element *E = ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())).front(); E; E = E->next()) {
+ for (const Map<StringName, ShaderLanguage::FunctionInfo>::Element *E = ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())).front(); E; E = E->next()) {
- for (const Map<StringName, ShaderLanguage::DataType>::Element *F = E->get().front(); F; F = F->next()) {
+ for (const Map<StringName, ShaderLanguage::DataType>::Element *F = E->get().built_ins.front(); F; F = F->next()) {
keywords.push_back(F->key());
}
}
@@ -197,8 +197,6 @@ void ShaderTextEditor::_validate_script() {
}
void ShaderTextEditor::_bind_methods() {
-
- //ADD_SIGNAL( MethodInfo("script_changed") );
}
ShaderTextEditor::ShaderTextEditor() {
@@ -282,6 +280,7 @@ void ShaderEditor::_editor_settings_changed() {
shader_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
shader_editor->get_text_edit()->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size"));
shader_editor->get_text_edit()->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type"));
+ shader_editor->get_text_edit()->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent"));
shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs"));
shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers"));
shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting"));
@@ -290,6 +289,8 @@ void ShaderEditor::_editor_settings_changed() {
shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing"));
shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
+ shader_editor->get_text_edit()->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling"));
+ shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
}
void ShaderEditor::_bind_methods() {
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index a1a60dac71..a5f55835f0 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -53,6 +53,9 @@
#define GIZMO_RING_HALF_WIDTH 0.1
//#define GIZMO_SCALE_DEFAULT 0.28
#define GIZMO_SCALE_DEFAULT 0.15
+#define GIZMO_PLANE_SIZE 0.2
+#define GIZMO_PLANE_DST 0.3
+#define GIZMO_CIRCLE_SIZE 0.9
#define ZOOM_MIN_DISTANCE 0.001
#define ZOOM_MULTIPLIER 1.08
@@ -591,6 +594,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
float grabber_radius = gs * GIZMO_ARROW_SIZE;
Vector3 r;
+
if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * 10000.0, grabber_pos, grabber_radius, &r)) {
float d = r.distance_to(ray_pos);
if (d < col_d) {
@@ -600,17 +604,49 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
}
}
+ bool is_plane_translate = false;
+ // second try
+ if (col_axis == -1) {
+ col_d = 1e20;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized();
+ Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized();
+
+ Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST);
+
+ Vector3 r;
+ Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
+
+ if (plane.intersects_ray(ray_pos, ray, &r)) {
+
+ float dist = r.distance_to(grabber_pos);
+ if (dist < (gs * GIZMO_PLANE_SIZE)) {
+
+ float d = ray_pos.distance_to(r);
+ if (d < col_d) {
+ col_d = d;
+ col_axis = i;
+
+ is_plane_translate = true;
+ }
+ }
+ }
+ }
+ }
+
if (col_axis != -1) {
if (p_highlight_only) {
- spatial_editor->select_gizmo_highlight_axis(col_axis);
+ spatial_editor->select_gizmo_highlight_axis(col_axis + (is_plane_translate ? 6 : 0));
} else {
- //handle rotate
+ //handle plane translate
_edit.mode = TRANSFORM_TRANSLATE;
_compute_edit(Point2(p_screenpos.x, p_screenpos.y));
- _edit.plane = TransformPlane(TRANSFORM_X_AXIS + col_axis);
+ _edit.plane = TransformPlane(TRANSFORM_X_AXIS + col_axis + (is_plane_translate ? 3 : 0));
}
return true;
}
@@ -630,7 +666,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
float dist = r.distance_to(gt.origin);
- if (dist > gs * (1 - GIZMO_RING_HALF_WIDTH) && dist < gs * (1 + GIZMO_RING_HALF_WIDTH)) {
+ if (dist > gs * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gs * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
float d = ray_pos.distance_to(r);
if (d < col_d) {
@@ -929,7 +965,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (get_selected_count() == 0)
break; //bye
- //handle rotate
+ //handle translate
_edit.mode = TRANSFORM_TRANSLATE;
_compute_edit(b->get_position());
break;
@@ -1183,6 +1219,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 motion_mask;
Plane plane;
+ bool plane_mv;
switch (_edit.plane) {
case TRANSFORM_VIEW:
@@ -1201,6 +1238,21 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2);
plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
break;
+ case TRANSFORM_YZ:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2) + spatial_editor->get_gizmo_transform().basis.get_axis(1);
+ plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(0));
+ plane_mv = true;
+ break;
+ case TRANSFORM_XZ:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2) + spatial_editor->get_gizmo_transform().basis.get_axis(0);
+ plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(1));
+ plane_mv = true;
+ break;
+ case TRANSFORM_XY:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0) + spatial_editor->get_gizmo_transform().basis.get_axis(1);
+ plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(2));
+ plane_mv = true;
+ break;
}
Vector3 intersection;
@@ -1214,7 +1266,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
//_validate_selection();
Vector3 motion = intersection - click;
if (motion_mask != Vector3()) {
- motion = motion_mask.dot(motion) * motion_mask;
+ if (plane_mv)
+ motion *= motion_mask;
+ else
+ motion = motion_mask.dot(motion) * motion_mask;
}
//set_message("Translating: "+motion);
@@ -2194,6 +2249,14 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
VS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF);
VS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i], layer);
+ move_plane_gizmo_instance[i] = VS::get_singleton()->instance_create();
+ VS::get_singleton()->instance_set_base(move_plane_gizmo_instance[i], spatial_editor->get_move_plane_gizmo(i)->get_rid());
+ VS::get_singleton()->instance_set_scenario(move_plane_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
+ VS::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], false);
+ //VS::get_singleton()->instance_geometry_set_flag(move_plane_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
+ VS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_plane_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF);
+ VS::get_singleton()->instance_set_layer_mask(move_plane_gizmo_instance[i], layer);
+
rotate_gizmo_instance[i] = VS::get_singleton()->instance_create();
VS::get_singleton()->instance_set_base(rotate_gizmo_instance[i], spatial_editor->get_rotate_gizmo(i)->get_rid());
VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
@@ -2208,6 +2271,7 @@ void SpatialEditorViewport::_finish_gizmo_instances() {
for (int i = 0; i < 3; i++) {
VS::get_singleton()->free(move_gizmo_instance[i]);
+ VS::get_singleton()->free(move_plane_gizmo_instance[i]);
VS::get_singleton()->free(rotate_gizmo_instance[i]);
}
}
@@ -2299,6 +2363,8 @@ void SpatialEditorViewport::update_transform_gizmo_view() {
for (int i = 0; i < 3; i++) {
VisualServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform);
VisualServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_MOVE));
+ VisualServer::get_singleton()->instance_set_transform(move_plane_gizmo_instance[i], xform);
+ VisualServer::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_MOVE));
VisualServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], xform);
VisualServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE));
}
@@ -3152,6 +3218,7 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
for (int i = 0; i < 3; i++) {
move_gizmo[i]->surface_set_material(0, i == p_axis ? gizmo_hl : gizmo_color[i]);
+ move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? gizmo_hl : plane_gizmo_color[i]);
rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_hl : gizmo_color[i]);
}
}
@@ -3195,7 +3262,7 @@ void SpatialEditor::update_transform_gizmo() {
gizmo.transform.origin = pcenter;
gizmo.transform.basis = gizmo_basis;
- for (int i = 0; i < VIEWPORTS_COUNT; i++) {
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->update_transform_gizmo_view();
}
}
@@ -3345,7 +3412,7 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
Array vp = d["viewports"];
ERR_FAIL_COND(vp.size() > 4);
- for (int i = 0; i < VIEWPORTS_COUNT; i++) {
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->set_state(vp[i]);
}
}
@@ -3742,23 +3809,26 @@ void SpatialEditor::_init_indicators() {
gizmo_hl = Ref<SpatialMaterial>(memnew(SpatialMaterial));
gizmo_hl->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- gizmo_hl->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ gizmo_hl->set_on_top_of_alpha();
gizmo_hl->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
gizmo_hl->set_albedo(Color(1, 1, 1, gizmo_alph + 0.2f));
+ gizmo_hl->set_cull_mode(SpatialMaterial::CULL_DISABLED);
for (int i = 0; i < 3; i++) {
move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
+ move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ mat->set_on_top_of_alpha();
mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
Color col;
col[i] = 1.0;
col.a = gizmo_alph;
mat->set_albedo(col);
+
gizmo_color[i] = mat;
Vector3 ivec;
@@ -3816,17 +3886,60 @@ void SpatialEditor::_init_indicators() {
surftool->commit(move_gizmo[i]);
}
+ // plane translation
+ {
+ Ref<SurfaceTool> surftool = memnew(SurfaceTool);
+ surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
+
+ Vector3 vec = ivec2 - ivec3;
+ Vector3 plane[4] = {
+ vec * GIZMO_PLANE_DST,
+ vec * GIZMO_PLANE_DST + ivec2 * GIZMO_PLANE_SIZE,
+ vec * (GIZMO_PLANE_DST + GIZMO_PLANE_SIZE),
+ vec * GIZMO_PLANE_DST - ivec3 * GIZMO_PLANE_SIZE
+ };
+
+ Basis ma(ivec, Math_PI / 2);
+
+ Vector3 points[4] = {
+ ma.xform(plane[0]),
+ ma.xform(plane[1]),
+ ma.xform(plane[2]),
+ ma.xform(plane[3]),
+ };
+ surftool->add_vertex(points[0]);
+ surftool->add_vertex(points[1]);
+ surftool->add_vertex(points[2]);
+
+ surftool->add_vertex(points[0]);
+ surftool->add_vertex(points[2]);
+ surftool->add_vertex(points[3]);
+
+ Ref<SpatialMaterial> plane_mat = memnew(SpatialMaterial);
+ plane_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ plane_mat->set_on_top_of_alpha();
+ plane_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ plane_mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ Color col;
+ col[i] = 1.0;
+ col.a = gizmo_alph;
+ plane_mat->set_albedo(col);
+ plane_gizmo_color[i] = plane_mat; // needed, so we can draw planes from both sides
+ surftool->set_material(plane_mat);
+ surftool->commit(move_plane_gizmo[i]);
+ }
+
{
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
Vector3 circle[5] = {
- ivec * 0.02 + ivec2 * 0.02 + ivec2 * 1.0,
- ivec * -0.02 + ivec2 * 0.02 + ivec2 * 1.0,
- ivec * -0.02 + ivec2 * -0.02 + ivec2 * 1.0,
- ivec * 0.02 + ivec2 * -0.02 + ivec2 * 1.0,
- ivec * 0.02 + ivec2 * 0.02 + ivec2 * 1.0,
+ ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
+ ivec * -0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
+ ivec * -0.02 + ivec2 * -0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
+ ivec * 0.02 + ivec2 * -0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
+ ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
};
for (int k = 0; k < 33; k++) {
@@ -3956,6 +4069,20 @@ void SpatialEditor::_notification(int p_what) {
_finish_indicators();
memdelete(gizmos);
}
+ if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ tool_button[SpatialEditor::TOOL_MODE_SELECT]->set_icon(get_icon("ToolSelect", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_MODE_MOVE]->set_icon(get_icon("ToolMove", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons"));
+
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons"));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons"));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), get_icon("Panels2Alt", "EditorIcons"));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), get_icon("Panels3", "EditorIcons"));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), get_icon("Panels3Alt", "EditorIcons"));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), get_icon("Panels4", "EditorIcons"));
+ }
}
void SpatialEditor::add_control_to_menu_panel(Control *p_control) {
@@ -4029,15 +4156,15 @@ void SpatialEditor::_toggle_maximize_view(Object *p_viewport) {
if (!maximized) {
- for (int i = 0; i < VIEWPORTS_COUNT; i++) {
- if (i == index)
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
+ if (i == (uint32_t)index)
viewports[i]->set_area_as_parent_rect();
else
viewports[i]->hide();
}
} else {
- for (int i = 0; i < VIEWPORTS_COUNT; i++)
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++)
viewports[i]->show();
if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT)))
@@ -4081,7 +4208,7 @@ void SpatialEditor::clear() {
settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near", 0.1));
settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far", 1500.0));
- for (int i = 0; i < VIEWPORTS_COUNT; i++) {
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->reset();
}
@@ -4094,7 +4221,7 @@ void SpatialEditor::clear() {
}
}
- for (int i = 0; i < VIEWPORTS_COUNT; i++) {
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER), i == 0);
viewports[i]->viewport->set_as_audio_listener(i == 0);
@@ -4258,7 +4385,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
viewport_base = memnew(SpatialEditorViewportContainer);
shader_split->add_child(viewport_base);
viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
- for (int i = 0; i < VIEWPORTS_COUNT; i++) {
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i] = memnew(SpatialEditorViewport(this, editor, i));
viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view");
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index f2ebf942b2..db5abe2b53 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -205,6 +205,9 @@ private:
TRANSFORM_X_AXIS,
TRANSFORM_Y_AXIS,
TRANSFORM_Z_AXIS,
+ TRANSFORM_YZ,
+ TRANSFORM_XZ,
+ TRANSFORM_XY,
};
struct EditData {
@@ -242,7 +245,7 @@ private:
real_t zoom_indicator_delay;
- RID move_gizmo_instance[3], rotate_gizmo_instance[3];
+ RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[3];
String last_message;
String message;
@@ -404,8 +407,9 @@ private:
bool grid_enable[3]; //should be always visible if true
bool grid_enabled;
- Ref<ArrayMesh> move_gizmo[3], rotate_gizmo[3];
+ Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[3];
Ref<SpatialMaterial> gizmo_color[3];
+ Ref<SpatialMaterial> plane_gizmo_color[3];
Ref<SpatialMaterial> gizmo_hl;
int over_gizmo_handle;
@@ -551,6 +555,7 @@ public:
bool are_local_coords_enabled() const { return transform_menu->get_popup()->is_item_checked(transform_menu->get_popup()->get_item_index(SpatialEditor::MENU_TRANSFORM_LOCAL_COORDS)); }
Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
+ Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; }
Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
void update_transform_gizmo();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index c2c26bfe6c..7b40f69082 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -244,8 +244,22 @@ void SpriteFramesEditor::_down_pressed() {
void SpriteFramesEditor::_delete_pressed() {
+ ERR_FAIL_COND(!frames->has_animation(edited_anim));
+
if (tree->get_current() < 0)
return;
+
+ int to_delete = tree->get_current();
+ if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) {
+ return;
+ }
+
+ undo_redo->create_action(TTR("Delete Resource"));
+ undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete);
+ undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete);
+ undo_redo->add_do_method(this, "_update_library");
+ undo_redo->add_undo_method(this, "_update_library");
+ undo_redo->commit_action();
}
void SpriteFramesEditor::_animation_select() {
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 82b507bd49..38d1350b07 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -67,7 +67,7 @@ void TextureRegionEditor::_region_draw() {
if (snap_mode == SNAP_GRID) {
Size2 s = edit_draw->get_size();
- int last_cell;
+ int last_cell = 0;
if (snap_step.x != 0) {
if (snap_separation.x == 0)
@@ -406,7 +406,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
} else if (drag) {
if (edited_margin >= 0) {
- float new_margin;
+ float new_margin = 0;
if (edited_margin == 0)
new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom;
else if (edited_margin == 1)
@@ -415,6 +415,9 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom;
else if (edited_margin == 3)
new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom;
+ else
+ ERR_PRINT("Unexpected edited_margin");
+
if (new_margin < 0)
new_margin = 0;
static Margin m[4] = { MARGIN_TOP, MARGIN_BOTTOM, MARGIN_LEFT, MARGIN_RIGHT };
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index e042e9cc96..323a36154e 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1226,7 +1226,7 @@ ProjectManager::ProjectManager() {
String cp;
cp.push_back(0xA9);
cp.push_back(0);
- OS::get_singleton()->set_window_title(_MKSTR(VERSION_NAME) + String(" - ") + TTR("Project Manager") + " - " + cp + " 2008-2017 Juan Linietsky, Ariel Manzur.");
+ OS::get_singleton()->set_window_title(_MKSTR(VERSION_NAME) + String(" - ") + TTR("Project Manager") + " - " + cp + " 2008-2017 Juan Linietsky, Ariel Manzur & Godot Contributors");
HBoxContainer *top_hb = memnew(HBoxContainer);
vb->add_child(top_hb);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 94fce45733..9fd31f818e 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* project_settings.cpp */
+/* project_settings_editor.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -929,7 +929,7 @@ void ProjectSettingsEditor::_copy_to_platform(int p_which) {
String path = globals_editor->get_property_editor()->get_selected_path();
if (path == String()) {
- EditorNode::get_singleton()->show_warning(TTR("Select an setting item first!"));
+ EditorNode::get_singleton()->show_warning(TTR("Select a setting item first!"));
return;
}
@@ -1321,6 +1321,11 @@ void ProjectSettingsEditor::set_plugins_page() {
tab_container->set_current_tab(plugin_settings->get_index());
}
+TabContainer *ProjectSettingsEditor::get_tabs() {
+
+ return tab_container;
+}
+
void ProjectSettingsEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_item_selected"), &ProjectSettingsEditor::_item_selected);
@@ -1361,6 +1366,8 @@ void ProjectSettingsEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_toggle_search_bar"), &ProjectSettingsEditor::_toggle_search_bar);
ClassDB::bind_method(D_METHOD("_copy_to_platform_about_to_show"), &ProjectSettingsEditor::_copy_to_platform_about_to_show);
+
+ ClassDB::bind_method(D_METHOD("get_tabs"), &ProjectSettingsEditor::get_tabs);
}
ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index e4e2345692..e58ba9b1c0 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* project_settings.h */
+/* project_settings_editor.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -159,6 +159,8 @@ public:
void popup_project_settings();
void set_plugins_page();
+ TabContainer *get_tabs();
+
void queue_save();
ProjectSettingsEditor(EditorData *p_data);
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 34a3ab71db..a42fb41ee2 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -866,7 +866,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
if (!RES(v).is_null()) {
menu->add_icon_item(get_icon("Edit", "EditorIcons"), "Edit", OBJ_MENU_EDIT);
- menu->add_icon_item(get_icon("Del", "EditorIcons"), "Clear", OBJ_MENU_CLEAR);
+ menu->add_icon_item(get_icon("Clear", "EditorIcons"), "Clear", OBJ_MENU_CLEAR);
menu->add_icon_item(get_icon("Duplicate", "EditorIcons"), "Make Unique", OBJ_MENU_MAKE_UNIQUE);
RES r = v;
if (r.is_valid() && r->get_path().is_resource_file()) {
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index c71cc5af3f..b92ebed167 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -171,33 +171,50 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str
Pair<String, Ref<Texture> > pair;
pair.first = file;
pair.second = get_icon((has_icon(efsd->get_file_type(i), ei) ? efsd->get_file_type(i) : ot), ei);
+ list.push_back(pair);
+ }
+ }
+
+ if (add_directories) {
+ for (int i = 0; i < efsd->get_subdir_count(); i++) {
- if (search_text != String() && list.size() > 0) {
+ _parse_fs(efsd->get_subdir(i), list);
+ }
+ }
+}
- float this_sim = _path_cmp(search_text, file);
- float other_sim = _path_cmp(list[0].first, file);
- int pos = 1;
+Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<String, Ref<Texture> > > &list) {
- while (pos < list.size() && this_sim <= other_sim) {
- other_sim = _path_cmp(list[pos++].first, file);
- }
+ String search_text = search_box->get_text();
+ Vector<Pair<String, Ref<Texture> > > sorted_list;
- pos = this_sim >= other_sim ? pos - 1 : pos;
- list.insert(pos, pair);
+ if (search_text == String() || list.size() == 0)
+ return sorted_list;
- } else {
+ Vector<float> scores;
+ scores.resize(list.size());
+ for (int i = 0; i < list.size(); i++)
+ scores[i] = _path_cmp(search_text, list[i].first);
- list.push_back(pair);
- }
- }
- }
+ while (list.size() > 0) {
- if (add_directories) {
- for (int i = 0; i < efsd->get_subdir_count(); i++) {
+ float best_score = 0.0f;
+ int best_idx = 0;
- _parse_fs(efsd->get_subdir(i), list);
+ for (int i = 0; i < list.size(); i++) {
+ float current_score = scores[i];
+ if (current_score > best_score) {
+ best_score = current_score;
+ best_idx = i;
+ }
}
+
+ sorted_list.push_back(list[best_idx]);
+ list.remove(best_idx);
+ scores.remove(best_idx);
}
+
+ return sorted_list;
}
void EditorQuickOpen::_update_search() {
@@ -208,6 +225,7 @@ void EditorQuickOpen::_update_search() {
Vector<Pair<String, Ref<Texture> > > list;
_parse_fs(efsd, list);
+ list = _sort_fs(list);
for (int i = 0; i < list.size(); i++) {
TreeItem *ti = search_options->create_item(root);
diff --git a/editor/quick_open.h b/editor/quick_open.h
index 3f64dd8cf0..5b91965920 100644
--- a/editor/quick_open.h
+++ b/editor/quick_open.h
@@ -49,6 +49,7 @@ class EditorQuickOpen : public ConfirmationDialog {
void _sbox_input(const Ref<InputEvent> &p_ie);
void _parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture> > > &list);
+ Vector<Pair<String, Ref<Texture> > > _sort_fs(Vector<Pair<String, Ref<Texture> > > &list);
float _path_cmp(String search, String path) const;
void _confirmed();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index b87387ec6c..afdf48b314 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -736,6 +736,14 @@ void SceneTreeDock::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
clear_inherit_confirm->disconnect("confirmed", this, "_tool_selected");
} break;
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ button_add->set_icon(get_icon("Add", "EditorIcons"));
+ button_instance->set_icon(get_icon("Instance", "EditorIcons"));
+ button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
+ button_clear_script->set_icon(get_icon("ScriptRemove", "EditorIcons"));
+
+ filter->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ } break;
}
}
@@ -1755,8 +1763,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_separator();
}
- menu->add_icon_shortcut(get_icon("Up", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
- menu->add_icon_shortcut(get_icon("Down", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
+ menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
+ menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index d0e2e0c240..089c054b59 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -352,9 +352,16 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
/* Does file already exist */
DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- if (f->file_exists(p) && !(f->current_is_dir())) {
+ if (f->dir_exists(p)) {
+ is_new_script_created = false;
+ is_path_valid = false;
+ _msg_path_valid(false, TTR("Directory of the same name exists"));
+ } else if (f->file_exists(p)) {
is_new_script_created = false;
is_path_valid = true;
+ _msg_path_valid(true, TTR("File exists, will be reused"));
+ } else {
+ path_error_label->set_text("");
}
memdelete(f);
_update_dialog();
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 623e458aca..05e3feedb5 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -165,7 +165,7 @@ void EditorSettingsDialog::_update_shortcuts() {
section->set_custom_bg_color(1, get_color("prop_subsection", "Editor"));
}
- if (shortcut_filter.is_subsequence_ofi(sc->get_name())) {
+ if (shortcut_filter.is_subsequence_ofi(sc->get_name()) || shortcut_filter.is_subsequence_ofi(sc->get_as_text())) {
TreeItem *item = shortcuts->create_item(section);
item->set_text(0, sc->get_name());
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index be30369dfe..9c7ea506aa 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -176,10 +176,10 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
vs.push_back(Vector3(p_scale, -p_scale, 0));
vs.push_back(Vector3(-p_scale, -p_scale, 0));
- uv.push_back(Vector2(1, 0));
uv.push_back(Vector2(0, 0));
- uv.push_back(Vector2(0, 1));
+ uv.push_back(Vector2(1, 0));
uv.push_back(Vector2(1, 1));
+ uv.push_back(Vector2(0, 1));
Ref<ArrayMesh> mesh = memnew(ArrayMesh);
Array a;
@@ -298,12 +298,23 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
}
void EditorSpatialGizmo::add_solid_box(Ref<Material> &p_material, Vector3 size) {
+ ERR_FAIL_COND(!spatial_node);
+
CubeMesh cubem;
cubem.set_size(size);
Ref<ArrayMesh> m = memnew(ArrayMesh);
m->add_surface_from_arrays(cubem.surface_get_primitive_type(0), cubem.surface_get_arrays(0));
m->surface_set_material(0, p_material);
add_mesh(m);
+
+ Instance ins;
+ ins.mesh = m;
+ if (valid) {
+ ins.create_instance(spatial_node);
+ VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
+ }
+
+ instances.push_back(ins);
}
void EditorSpatialGizmo::set_spatial_node(Spatial *p_node) {
@@ -569,7 +580,7 @@ Ref<SpatialMaterial> EditorSpatialGizmo::create_material(const String &p_name, c
}
if (p_on_top && is_selected()) {
- line_material->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ line_material->set_on_top_of_alpha();
}
line_material->set_albedo(color);
@@ -613,7 +624,7 @@ Ref<SpatialMaterial> EditorSpatialGizmo::create_icon_material(const String &p_na
icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
if (p_on_top && is_selected()) {
- icon->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ icon->set_on_top_of_alpha();
}
SpatialEditorGizmos::singleton->material_cache[name] = icon;
@@ -634,9 +645,13 @@ void EditorSpatialGizmo::_bind_methods() {
BIND_VMETHOD(MethodInfo("redraw"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "get_handle_name", PropertyInfo(Variant::INT, "index")));
- BIND_VMETHOD(MethodInfo("get_handle_value:Variant", PropertyInfo(Variant::INT, "index")));
- BIND_VMETHOD(MethodInfo("set_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::OBJECT, "camera:Camera"), PropertyInfo(Variant::VECTOR2, "point")));
- MethodInfo cm = MethodInfo("commit_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::NIL, "restore:Variant"), PropertyInfo(Variant::BOOL, "cancel"));
+
+ MethodInfo hvget(Variant::NIL, "get_handle_value", PropertyInfo(Variant::INT, "index"));
+ hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ BIND_VMETHOD(hvget);
+
+ BIND_VMETHOD(MethodInfo("set_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::VECTOR2, "point")));
+ MethodInfo cm = MethodInfo("commit_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
cm.default_arguments.push_back(false);
BIND_VMETHOD(cm);
}
@@ -855,7 +870,7 @@ void LightSpatialGizmo::redraw() {
if (Object::cast_to<SpotLight>(light)) {
Ref<Material> material = create_material("light_spot_material", gizmo_color, true);
- Ref<Material> icon = create_icon_material("light_spot_icon", SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
+ Ref<Material> icon = create_icon_material("light_spot_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpotLight", "EditorIcons"));
clear();
@@ -873,10 +888,6 @@ void LightSpatialGizmo::redraw() {
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
- /*points.push_back(Vector3(a.x,0,a.y));
- points.push_back(Vector3(b.x,0,b.y));
- points.push_back(Vector3(0,a.x,a.y));
- points.push_back(Vector3(0,b.x,b.y));*/
points.push_back(Vector3(a.x, a.y, -d));
points.push_back(Vector3(b.x, b.y, -d));
@@ -1145,6 +1156,7 @@ void CameraSpatialGizmo::redraw() {
Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/camera");
Ref<Material> material = create_material("camera_material", gizmo_color);
+ Ref<Material> icon = create_icon_material("camera_icon", SpatialEditor::get_singleton()->get_icon("GizmoCamera", "EditorIcons"));
switch (camera->get_projection()) {
@@ -1215,6 +1227,7 @@ void CameraSpatialGizmo::redraw() {
add_lines(lines, material);
add_collision_segments(lines);
+ add_unscaled_billboard(icon, 0.05);
add_handles(handles);
}
@@ -2340,6 +2353,7 @@ void ParticlesGizmo::redraw() {
Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/particles");
Ref<Material> material = create_material("particles_material", gizmo_color);
+ Ref<Material> icon = create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoParticles", "EditorIcons"));
add_lines(lines, material);
add_collision_segments(lines);
@@ -2352,6 +2366,7 @@ void ParticlesGizmo::redraw() {
}
//add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
+ add_unscaled_billboard(icon, 0.05);
add_handles(handles);
}
ParticlesGizmo::ParticlesGizmo(Particles *p_particles) {
@@ -2497,6 +2512,7 @@ void ReflectionProbeGizmo::redraw() {
Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/reflection_probe");
Ref<Material> material = create_material("reflection_probe_material", gizmo_color);
+ Ref<Material> icon = create_icon_material("reflection_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoReflectionProbe", "EditorIcons"));
Color gizmo_color_internal = gizmo_color;
gizmo_color_internal.a = 0.5;
@@ -2513,6 +2529,7 @@ void ReflectionProbeGizmo::redraw() {
}
//add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
+ add_unscaled_billboard(icon, 0.05);
add_collision_segments(lines);
add_handles(handles);
}
@@ -2586,6 +2603,7 @@ void GIProbeGizmo::redraw() {
Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/gi_probe");
Ref<Material> material = create_material("gi_probe_material", gizmo_color);
+ Ref<Material> icon = create_icon_material("gi_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoGIProbe", "EditorIcons"));
Color gizmo_color_internal = gizmo_color;
gizmo_color_internal.a = 0.1;
Ref<Material> material_internal = create_material("gi_probe_internal_material", gizmo_color_internal);
@@ -2671,6 +2689,7 @@ void GIProbeGizmo::redraw() {
add_solid_box(solid_material, aabb.get_size());
}
+ add_unscaled_billboard(icon, 0.05);
add_handles(handles);
}
GIProbeGizmo::GIProbeGizmo(GIProbe *p_probe) {
@@ -3392,7 +3411,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- handle_material->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ handle_material->set_on_top_of_alpha();
handle_material->set_albedo(Color(0.8, 0.8, 0.8));
handle_material_billboard = handle_material->duplicate();
handle_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
@@ -3407,11 +3426,11 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
handle2_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
handle2_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
handle2_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- handle2_material->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ handle2_material->set_on_top_of_alpha();
handle2_material_billboard = handle2_material->duplicate();
handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
- handle2_material_billboard->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ handle2_material_billboard->set_on_top_of_alpha();
EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2));
EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1));
@@ -3471,7 +3490,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
skeleton_material = create_line_material(Color(0.6, 1.0, 0.3));
skeleton_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
skeleton_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- skeleton_material->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ skeleton_material->set_on_top_of_alpha();
skeleton_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
//position 3D Shared mesh
diff --git a/main/main.cpp b/main/main.cpp
index 00cb43b0a8..7b2a890a8e 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -69,7 +69,6 @@
#include "core/io/file_access_zip.h"
#include "core/io/stream_peer_ssl.h"
#include "core/io/stream_peer_tcp.h"
-#include "core/os/thread.h"
#include "main/input_default.h"
#include "performance.h"
#include "translation.h"
@@ -112,6 +111,8 @@ static int init_screen = -1;
static bool use_vsync = true;
static bool editor = false;
static bool show_help = false;
+static bool disable_render_loop = false;
+static int fixed_fps = -1;
static OS::ProcessID allow_focus_steal_pid = 0;
@@ -191,6 +192,8 @@ void Main::print_help(const char *p_binary) {
#endif
OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n");
+ OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n");
+ OS::get_singleton()->print(" --fixed-fps <fps> Forces a fixed ratio between process and fixed_process timing, for use when precision is required, or when rendering to video files. Setting this will disable real-time syncronization, so that run speed is only capped by performance\n");
OS::get_singleton()->print("\n");
OS::get_singleton()->print("Standalone tools:\n");
@@ -568,6 +571,16 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->print("Missing editor PID argument, aborting.\n");
goto error;
}
+ } else if (I->get() == "--disable-render-loop") {
+ disable_render_loop = true;
+ } else if (I->get() == "--fixed-fps") {
+ if (I->next()) {
+ fixed_fps = I->next()->get().to_int();
+ N = I->next()->next();
+ } else {
+ OS::get_singleton()->print("Missing fixed-fps argument, aborting.\n");
+ goto error;
+ }
} else {
//test for game path
@@ -886,7 +899,11 @@ error:
return ERR_INVALID_PARAMETER;
}
-Error Main::setup2() {
+Error Main::setup2(Thread::ID p_main_tid_override) {
+
+ if (p_main_tid_override) {
+ Thread::_main_thread_id = p_main_tid_override;
+ }
OS::get_singleton()->initialize(video_mode, video_driver_idx, audio_driver_idx);
if (init_use_custom_pos) {
@@ -1095,10 +1112,20 @@ bool Main::start() {
test = args[i + 1];
} else if (args[i] == "--export") {
editor = true; //needs editor
- _export_preset = args[i + 1];
+ if (i + 1 < args.size()) {
+ _export_preset = args[i + 1];
+ } else {
+ ERR_PRINT("Export preset name not specified");
+ return false;
+ }
} else if (args[i] == "--export-debug") {
editor = true; //needs editor
- _export_preset = args[i + 1];
+ if (i + 1 < args.size()) {
+ _export_preset = args[i + 1];
+ } else {
+ ERR_PRINT("Export preset name not specified");
+ return false;
+ }
export_debug = true;
} else {
// The parameter does not match anything known, don't skip the next argument
@@ -1502,6 +1529,9 @@ bool Main::iteration() {
uint64_t ticks_elapsed = ticks - last_ticks;
double step = (double)ticks_elapsed / 1000000.0;
+ if (fixed_fps != -1)
+ step = 1.0 / fixed_fps;
+
float frame_slice = 1.0 / Engine::get_singleton()->get_iterations_per_second();
Engine::get_singleton()->_frame_step = step;
@@ -1518,7 +1548,7 @@ bool Main::iteration() {
last_ticks = ticks;
- if (step > frame_slice * 8)
+ if (fixed_fps == -1 && step > frame_slice * 8)
step = frame_slice * 8;
time_accum += step;
@@ -1571,7 +1601,7 @@ bool Main::iteration() {
VisualServer::get_singleton()->sync(); //sync if still drawing from previous frames.
- if (OS::get_singleton()->can_draw()) {
+ if (OS::get_singleton()->can_draw() && !disable_render_loop) {
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
if (VisualServer::get_singleton()->has_changed()) {
@@ -1622,6 +1652,9 @@ bool Main::iteration() {
frames = 0;
}
+ if (fixed_fps != -1)
+ return exit;
+
if (OS::get_singleton()->is_in_low_processor_usage_mode() || !OS::get_singleton()->can_draw())
OS::get_singleton()->delay_usec(16600); //apply some delay to force idle time (results in about 60 FPS max)
else {
diff --git a/main/main.h b/main/main.h
index f8db0225bf..2c1d42a163 100644
--- a/main/main.h
+++ b/main/main.h
@@ -34,6 +34,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
+#include "core/os/thread.h"
#include "error_list.h"
#include "typedefs.h"
@@ -49,7 +50,7 @@ class Main {
public:
static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true);
- static Error setup2();
+ static Error setup2(Thread::ID p_main_tid_override = 0);
static bool start();
static bool iteration();
static void cleanup();
diff --git a/main/tests/test_main.cpp b/main/tests/test_main.cpp
index 794bdb757b..645db2826e 100644
--- a/main/tests/test_main.cpp
+++ b/main/tests/test_main.cpp
@@ -37,6 +37,7 @@
#include "test_image.h"
#include "test_io.h"
#include "test_math.h"
+#include "test_ordered_hash_map.h"
#include "test_physics.h"
#include "test_physics_2d.h"
#include "test_render.h"
@@ -130,6 +131,11 @@ MainLoop *test_main(String p_test, const List<String> &p_args) {
return TestImage::test();
}
+ if (p_test == "ordered_hash_map") {
+
+ return TestOrderedHashMap::test();
+ }
+
return NULL;
}
diff --git a/main/tests/test_ordered_hash_map.cpp b/main/tests/test_ordered_hash_map.cpp
new file mode 100644
index 0000000000..89f4bf8593
--- /dev/null
+++ b/main/tests/test_ordered_hash_map.cpp
@@ -0,0 +1,171 @@
+/*************************************************************************/
+/* test_ordered_hash_map.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "ordered_hash_map.h"
+#include "os/os.h"
+#include "pair.h"
+#include "vector.h"
+
+namespace TestOrderedHashMap {
+
+bool test_insert() {
+ OrderedHashMap<int, int> map;
+ OrderedHashMap<int, int>::Element e = map.insert(42, 84);
+
+ return e && e.key() == 42 && e.get() == 84 && e.value() == 84 && map[42] == 84 && map.has(42) && map.find(42);
+}
+
+bool test_insert_overwrite() {
+ OrderedHashMap<int, int> map;
+ map.insert(42, 84);
+ map.insert(42, 1234);
+
+ return map[42] == 1234;
+}
+
+bool test_erase_via_element() {
+ OrderedHashMap<int, int> map;
+ OrderedHashMap<int, int>::Element e = map.insert(42, 84);
+
+ map.erase(e);
+ return !e && !map.has(42) && !map.find(42);
+}
+
+bool test_erase_via_key() {
+ OrderedHashMap<int, int> map;
+ map.insert(42, 84);
+ map.erase(42);
+ return !map.has(42) && !map.find(42);
+}
+
+bool test_size() {
+ OrderedHashMap<int, int> map;
+ map.insert(42, 84);
+ map.insert(123, 84);
+ map.insert(123, 84);
+ map.insert(0, 84);
+ map.insert(123485, 84);
+
+ return map.size() == 4;
+}
+
+bool test_iteration() {
+ OrderedHashMap<int, int> map;
+ map.insert(42, 84);
+ map.insert(123, 12385);
+ map.insert(0, 12934);
+ map.insert(123485, 1238888);
+ map.insert(123, 111111);
+
+ Vector<Pair<int, int> > expected;
+ expected.push_back(Pair<int, int>(42, 84));
+ expected.push_back(Pair<int, int>(123, 111111));
+ expected.push_back(Pair<int, int>(0, 12934));
+ expected.push_back(Pair<int, int>(123485, 1238888));
+
+ int idx = 0;
+ for (OrderedHashMap<int, int>::Element E = map.front(); E; E = E.next()) {
+ if (expected[idx] != Pair<int, int>(E.key(), E.value())) {
+ return false;
+ }
+ ++idx;
+ }
+ return true;
+}
+
+bool test_const_iteration(const OrderedHashMap<int, int> &map) {
+ Vector<Pair<int, int> > expected;
+ expected.push_back(Pair<int, int>(42, 84));
+ expected.push_back(Pair<int, int>(123, 111111));
+ expected.push_back(Pair<int, int>(0, 12934));
+ expected.push_back(Pair<int, int>(123485, 1238888));
+
+ int idx = 0;
+ for (OrderedHashMap<int, int>::ConstElement E = map.front(); E; E = E.next()) {
+ if (expected[idx] != Pair<int, int>(E.key(), E.value())) {
+ return false;
+ }
+ ++idx;
+ }
+ return true;
+}
+
+bool test_const_iteration() {
+ OrderedHashMap<int, int> map;
+ map.insert(42, 84);
+ map.insert(123, 12385);
+ map.insert(0, 12934);
+ map.insert(123485, 1238888);
+ map.insert(123, 111111);
+
+ return test_const_iteration(map);
+}
+
+typedef bool (*TestFunc)(void);
+
+TestFunc test_funcs[] = {
+
+ test_insert,
+ test_insert_overwrite,
+ test_erase_via_element,
+ test_erase_via_key,
+ test_size,
+ test_iteration,
+ test_const_iteration,
+ 0
+
+};
+
+MainLoop *test() {
+
+ int count = 0;
+ int passed = 0;
+
+ while (true) {
+ if (!test_funcs[count])
+ break;
+ bool pass = test_funcs[count]();
+ if (pass)
+ passed++;
+ OS::get_singleton()->print("\t%s\n", pass ? "PASS" : "FAILED");
+
+ count++;
+ }
+
+ OS::get_singleton()->print("\n\n\n");
+ OS::get_singleton()->print("*************\n");
+ OS::get_singleton()->print("***TOTALS!***\n");
+ OS::get_singleton()->print("*************\n");
+
+ OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
+
+ return NULL;
+}
+} // namespace TestOrderedHashMap \ No newline at end of file
diff --git a/main/tests/test_ordered_hash_map.h b/main/tests/test_ordered_hash_map.h
new file mode 100644
index 0000000000..0cde250f56
--- /dev/null
+++ b/main/tests/test_ordered_hash_map.h
@@ -0,0 +1,38 @@
+/*************************************************************************/
+/* test_ordered_hash_map.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef TEST_ORDERED_HASH_MAP_H
+#define TEST_ORDERED_HASH_MAP_H
+
+namespace TestOrderedHashMap {
+
+MainLoop *test();
+}
+
+#endif
diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp
index a0539f4bdf..ddb2ed5e75 100644
--- a/main/tests/test_shader_lang.cpp
+++ b/main/tests/test_shader_lang.cpp
@@ -316,8 +316,9 @@ MainLoop *test() {
SL sl;
print_line("tokens:\n\n" + sl.token_debug(code));
- Map<StringName, Map<StringName, SL::DataType> > dt;
- dt["fragment"]["ALBEDO"] = SL::TYPE_VEC3;
+ Map<StringName, SL::FunctionInfo> dt;
+ dt["fragment"].built_ins["ALBEDO"] = SL::TYPE_VEC3;
+ dt["fragment"].can_discard = true;
Set<String> rm;
rm.insert("popo");
diff --git a/methods.py b/methods.py
index 25093ac530..ec7e658a3b 100644
--- a/methods.py
+++ b/methods.py
@@ -1680,6 +1680,59 @@ def detect_visual_c_compiler_version(tools_env):
return vc_chosen_compiler_str
+def find_visual_c_batch_file(env):
+ from SCons.Tool.MSCommon.vc import get_default_version, get_host_target, find_batch_file
+
+ version = get_default_version(env)
+ (host_platform, target_platform,req_target_platform) = get_host_target(env)
+ return find_batch_file(env, version, host_platform, target_platform)[0]
+
+
+def generate_vs_project(env, num_jobs):
+ batch_file = find_visual_c_batch_file(env)
+ if batch_file:
+ def build_commandline(commands):
+ common_build_prefix = ['cmd /V /C set "plat=$(PlatformTarget)"',
+ '(if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64"))',
+ 'set "tools=yes"',
+ '(if "$(Configuration)"=="release" (set "tools=no"))',
+ 'call "' + batch_file + '" !plat!']
+
+ result = " ^& ".join(common_build_prefix + [commands])
+ # print("Building commandline: ", result)
+ return result
+
+ env.AddToVSProject(env.core_sources)
+ env.AddToVSProject(env.main_sources)
+ env.AddToVSProject(env.modules_sources)
+ env.AddToVSProject(env.scene_sources)
+ env.AddToVSProject(env.servers_sources)
+ env.AddToVSProject(env.editor_sources)
+
+ env['MSVSBUILDCOM'] = build_commandline('scons platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs))
+ env['MSVSREBUILDCOM'] = build_commandline('scons platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j' + str(num_jobs))
+ env['MSVSCLEANCOM'] = build_commandline('scons --clean platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs))
+
+ # This version information (Win32, x64, Debug, Release, Release_Debug seems to be
+ # required for Visual Studio to understand that it needs to generate an NMAKE
+ # project. Do not modify without knowing what you are doing.
+ debug_variants = ['debug|Win32'] + ['debug|x64']
+ release_variants = ['release|Win32'] + ['release|x64']
+ release_debug_variants = ['release_debug|Win32'] + ['release_debug|x64']
+ variants = debug_variants + release_variants + release_debug_variants
+ debug_targets = ['bin\\godot.windows.tools.32.exe'] + ['bin\\godot.windows.tools.64.exe']
+ release_targets = ['bin\\godot.windows.opt.32.exe'] + ['bin\\godot.windows.opt.64.exe']
+ release_debug_targets = ['bin\\godot.windows.opt.tools.32.exe'] + ['bin\\godot.windows.opt.tools.64.exe']
+ targets = debug_targets + release_targets + release_debug_targets
+ msvproj = env.MSVSProject(target=['#godot' + env['MSVSPROJECTSUFFIX']],
+ incs=env.vs_incs,
+ srcs=env.vs_srcs,
+ runfile=targets,
+ buildtarget=targets,
+ auto_build_solution=1,
+ variant=variants)
+ else:
+ print("Could not locate Visual Studio batch file for setting up the build environment. Not generating VS project.")
def precious_program(env, program, sources, **args):
program = env.ProgramOriginal(program, sources, **args)
diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format
index 0971ebe23a..d2d65a7428 100755
--- a/misc/hooks/pre-commit-clang-format
+++ b/misc/hooks/pre-commit-clang-format
@@ -1,6 +1,6 @@
#!/bin/bash
-# git pre-commit hook that runs an clang-format stylecheck.
+# git pre-commit hook that runs a clang-format stylecheck.
# Features:
# - abort commit when commit does not comply with the style guidelines
# - create a patch of the proposed style changes
@@ -97,7 +97,7 @@ do
# The sed call is necessary to transform the patch from
# --- $file timestamp
# +++ - timestamp
- # to both lines working on the same file and having a a/ and b/ prefix.
+ # to both lines working on the same file and having a/ and b/ prefix.
# Else it can not be applied with 'git apply'.
"$CLANG_FORMAT" -style=file "$file" | \
diff -u "$file" - | \
diff --git a/misc/scripts/svgs_2_pngs.py b/misc/scripts/svgs_2_pngs.py
deleted file mode 100644
index ff6d6d851f..0000000000
--- a/misc/scripts/svgs_2_pngs.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Basic exporter for svg icons
-
-from os import listdir
-from os.path import isfile, join, dirname, realpath
-import subprocess
-import sys
-
-import rsvg
-import cairo
-
-last_svg_path = None
-last_svg_data = None
-
-SCRIPT_FOLDER = dirname(realpath(__file__)) + '/'
-theme_dir_base = SCRIPT_FOLDER + '../../scene/resources/default_theme/'
-theme_dir_source = theme_dir_base + 'source/'
-icons_dir_base = SCRIPT_FOLDER + '../../editor/icons/'
-icons_dir_2x = icons_dir_base + '2x/'
-icons_dir_source = icons_dir_base + 'source/'
-
-
-def svg_to_png(svg_path, png_path, dpi):
- global last_svg_path, last_svg_data
-
- zoom = int(dpi / 90)
- if last_svg_path != svg_path:
- last_svg_data = open(svg_path, 'r').read()
- last_svg_path = svg_path
- svg = rsvg.Handle(data=last_svg_data)
- img = cairo.ImageSurface(
- cairo.FORMAT_ARGB32,
- svg.props.width * zoom,
- svg.props.height * zoom
- )
- ctx = cairo.Context(img)
- ctx.set_antialias(cairo.ANTIALIAS_DEFAULT)
- ctx.scale(zoom, zoom)
- svg.render_cairo(ctx)
- img.write_to_png('%s.png' % png_path)
- svg.close()
-
-
-def export_icons():
- svgs_path = icons_dir_source
-
- file_names = [f for f in listdir(svgs_path) if isfile(join(svgs_path, f))]
-
- for file_name in file_names:
- # name without extensions
- name_only = file_name.replace('.svg', '')
-
- out_icon_names = [name_only] # export to a png with the same file name
- theme_out_icon_names = []
- # special cases
- if special_icons.has_key(name_only):
- special_icon = special_icons[name_only]
- if type(special_icon) is dict:
- if special_icon.get('avoid_self'):
- out_icon_names = []
- if special_icon.has_key('output_names'):
- out_icon_names += special_icon['output_names']
- if special_icon.has_key('theme_output_names'):
- theme_out_icon_names += special_icon['theme_output_names']
-
- source_path = '%s%s.svg' % (svgs_path, name_only)
-
- for out_icon_name in out_icon_names:
- svg_to_png(source_path, icons_dir_base + out_icon_name, 90)
- svg_to_png(source_path, icons_dir_2x + out_icon_name, 180)
- for theme_out_icon_name in theme_out_icon_names:
- svg_to_png(source_path, theme_dir_base + theme_out_icon_name, 90)
-
-
-def export_theme():
- svgs_path = theme_dir_source
- file_names = [f for f in listdir(svgs_path) if isfile(join(svgs_path, f))]
-
- for file_name in file_names:
- # name without extensions
- name_only = file_name.replace('.svg', '')
-
- out_icon_names = [name_only] # export to a png with the same file name
- # special cases
- if theme_icons.has_key(name_only):
- special_icon = theme_icons[name_only]
- if type(special_icon) is dict:
- if special_icon.has_key('output_names'):
- out_icon_names += special_icon['output_names']
-
- source_path = '%s%s.svg' % (svgs_path, name_only)
-
- for out_icon_name in out_icon_names:
- svg_to_png(source_path, theme_dir_base + out_icon_name, 90)
-
-
-# special cases for icons that will be exported to multiple target pngs or that require transforms.
-special_icons = {
- 'icon_add_track': dict(
- output_names=['icon_add'],
- theme_output_names=['icon_add', 'icon_zoom_more']
- ),
- 'icon_new': dict(output_names=['icon_file']),
- 'icon_animation_tree_player': dict(output_names=['icon_animation_tree']),
- 'icon_tool_rotate': dict(
- output_names=['icon_reload'],
- theme_output_names=['icon_reload']
- ),
- 'icon_multi_edit': dict(output_names=['icon_multi_node_edit']),
- 'icon_load': dict(
- output_names=['icon_open']
- ),
- 'icon_folder': dict(
- theme_output_names=['icon_folder']
- ),
- 'icon_file_list': dict(output_names=['icon_enum']),
- 'icon_collision_2d': dict(output_names=['icon_collision_polygon_2d', 'icon_polygon_2d']),
- 'icon_class_list': dict(output_names=['icon_filesystem']),
- 'icon_color_ramp': dict(output_names=['icon_graph_color_ramp']),
- 'icon_translation': dict(output_names=['icon_p_hash_translation']),
- 'icon_shader': dict(output_names=['icon_shader_material', 'icon_material_shader']),
- 'icon_canvas_item_shader_graph': dict(output_names=['icon_material_shader_graph']),
-
- 'icon_color_pick': dict(theme_output_names=['icon_color_pick'], avoid_self=True),
- 'icon_play': dict(theme_output_names=['icon_play']),
- 'icon_stop': dict(theme_output_names=['icon_stop']),
- 'icon_zoom_less': dict(theme_output_names=['icon_zoom_less'], avoid_self=True),
- 'icon_zoom_reset': dict(theme_output_names=['icon_zoom_reset'], avoid_self=True),
- 'icon_snap': dict(theme_output_names=['icon_snap'])
-}
-
-theme_icons = {
- 'icon_close': dict(output_names=['close', 'close_hl']),
- 'tab_menu': dict(output_names=['tab_menu_hl'])
-}
-
-export_icons()
-export_theme()
diff --git a/modules/etc/SCsub b/modules/etc/SCsub
index 8f5937017e..9c3e703f11 100644
--- a/modules/etc/SCsub
+++ b/modules/etc/SCsub
@@ -34,4 +34,8 @@ env_etc.Append(CPPPATH=[thirdparty_dir])
env_etc.add_source_files(env.modules_sources, "*.cpp")
# upstream uses c++11
-env_etc.Append(CXXFLAGS="-std=gnu++11")
+env_etc.Append(CCFLAGS="-std=gnu++11")
+# -ffast-math seems to be incompatible with ec2comp on recent versions of
+# GCC and Clang
+if '-ffast-math' in env_etc['CCFLAGS']:
+ env_etc['CCFLAGS'].remove('-ffast-math')
diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp
index 9a15beb6eb..e86fd06d81 100644
--- a/modules/etc/image_etc.cpp
+++ b/modules/etc/image_etc.cpp
@@ -117,7 +117,7 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
return;
}
- int imgw = p_img->get_width(), imgh = p_img->get_height();
+ uint32_t imgw = p_img->get_width(), imgh = p_img->get_height();
ERR_FAIL_COND(next_power_of_2(imgw) != imgw || next_power_of_2(imgh) != imgh);
Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels);
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index 65970d48c1..f386f2b542 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -2,12 +2,16 @@
Import('env')
-env.add_source_files(env.modules_sources, "*.cpp")
-env.add_source_files(env.modules_sources, "godot/*.cpp")
+gdn_env = env.Clone()
-env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN'])
-env.Append(CPPPATH=['#modules/gdnative/'])
+gdn_env.add_source_files(env.modules_sources, "*.cpp")
+gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp")
+gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")
+
+gdn_env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN'])
+gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])
if "platform" in env and env["platform"] == "x11": # there has to be a better solution?
env.Append(LINKFLAGS=["-rdynamic"])
+
env.use_ptrcall = True
diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py
index 4f89ca0d4c..9f57b9bb74 100644
--- a/modules/gdnative/config.py
+++ b/modules/gdnative/config.py
@@ -1,7 +1,7 @@
def can_build(platform):
- return False
+ return True
def configure(env):
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 7faf21c5a1..6da538844a 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -40,7 +40,7 @@
const String init_symbol = "godot_gdnative_init";
const String terminate_symbol = "godot_gdnative_terminate";
-String GDNativeLibrary::platform_names[NUM_PLATFORMS] = {
+String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = {
"X11_32bit",
"X11_64bit",
"Windows_32bit",
@@ -48,11 +48,15 @@ String GDNativeLibrary::platform_names[NUM_PLATFORMS] = {
"OSX",
"Android",
- "iOS",
- "WebAssembly"
+ "iOS_32bit",
+ "iOS_64bit",
+
+ "WebAssembly",
+
+ ""
};
-String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = {
+String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS + 1] = {
"so",
"so",
"dll",
@@ -60,21 +64,30 @@ String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = {
"dylib",
"so",
+
+ "dylib",
"dylib",
- "wasm"
+ "wasm",
+
+ ""
};
-// TODO(karroffel): make this actually do the right thing.
GDNativeLibrary::Platform GDNativeLibrary::current_platform =
#if defined(X11_ENABLED)
- X11_64BIT;
+ (sizeof(void *) == 8 ? X11_64BIT : X11_32BIT);
#elif defined(WINDOWS_ENABLED)
- WINDOWS_64BIT;
+ (sizeof(void *) == 8 ? WINDOWS_64BIT : WINDOWS_32BIT);
#elif defined(OSX_ENABLED)
OSX;
+#elif defined(IPHONE_ENABLED)
+ (sizeof(void *) == 8 ? IOS_64BIT : IOS_32BIT);
+#elif defined(ANDROID_ENABLED)
+ ANDROID;
+#elif defined(JAVASCRIPT_ENABLED)
+ WASM;
#else
- X11_64BIT; // need a sensible default..
+ NUM_PLATFORMS;
#endif
GDNativeLibrary::GDNativeLibrary()
@@ -87,6 +100,11 @@ GDNativeLibrary::~GDNativeLibrary() {
void GDNativeLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_library_path", "platform", "path"), &GDNativeLibrary::set_library_path);
ClassDB::bind_method(D_METHOD("get_library_path", "platform"), &GDNativeLibrary::get_library_path);
+
+ ClassDB::bind_method(D_METHOD("is_singleton_gdnative"), &GDNativeLibrary::is_singleton_gdnative);
+ ClassDB::bind_method(D_METHOD("set_singleton_gdnative", "singleton"), &GDNativeLibrary::set_singleton_gdnative);
+
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton_gdnative"), "set_singleton_gdnative", "is_singleton_gdnative");
}
bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_value) {
@@ -151,7 +169,10 @@ String GDNativeLibrary::get_library_path(StringName p_platform) const {
}
String GDNativeLibrary::get_active_library_path() const {
- return library_paths[GDNativeLibrary::current_platform];
+ if (GDNativeLibrary::current_platform != NUM_PLATFORMS) {
+ return library_paths[GDNativeLibrary::current_platform];
+ }
+ return "";
}
GDNative::GDNative() {
@@ -159,7 +180,6 @@ GDNative::GDNative() {
}
GDNative::~GDNative() {
- // TODO(karroffel): implement ALL the things!
}
extern "C" void _api_anchor();
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index bec746a441..4753c7efe5 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -35,7 +35,7 @@
#include "os/thread_safe.h"
#include "resource.h"
-#include <godot/gdnative.h>
+#include "gdnative/gdnative.h"
class GDNativeLibrary : public Resource {
GDCLASS(GDNativeLibrary, Resource)
@@ -48,11 +48,17 @@ class GDNativeLibrary : public Resource {
// NOTE(karroffel): I heard OSX 32 bit is dead, so 64 only
OSX,
- // TODO(karroffel): all different android versions and archs
+ // Android .so files must be located in directories corresponding to Android ABI names:
+ // https://developer.android.com/ndk/guides/abis.html
+ // Android runtime will select the matching library depending on the device.
+ // The value here must simply point to the .so name, for example:
+ // "res://libmy_gdnative.so" or "libmy_gdnative.so",
+ // while in the project the actual paths can be "lib/android/armeabi-v7a/libmy_gdnative.so",
+ // "lib/android/arm64-v8a/libmy_gdnative.so".
ANDROID,
- // TODO(karroffe): all different iOS versions and archs
- IOS,
+ IOS_32BIT,
+ IOS_64BIT,
// TODO(karroffel): figure out how to deal with web stuff at all...
WASM,
@@ -64,14 +70,15 @@ class GDNativeLibrary : public Resource {
};
- static String platform_names[NUM_PLATFORMS];
- static String platform_lib_ext[NUM_PLATFORMS];
+ static String platform_names[NUM_PLATFORMS + 1];
+ static String platform_lib_ext[NUM_PLATFORMS + 1];
- // TODO(karroffel): make this actually do something lol.
static Platform current_platform;
String library_paths[NUM_PLATFORMS];
+ bool singleton_gdnative = false;
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
@@ -87,6 +94,9 @@ public:
String get_library_path(StringName p_platform) const;
String get_active_library_path() const;
+
+ _FORCE_INLINE_ bool is_singleton_gdnative() const { return singleton_gdnative; }
+ _FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; }
};
typedef godot_variant (*native_call_cb)(void *, godot_string *, godot_array *);
diff --git a/modules/gdnative/godot/array.cpp b/modules/gdnative/gdnative/array.cpp
index c15ba30ca2..51c023981f 100644
--- a/modules/gdnative/godot/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/array.h>
+#include "gdnative/array.h"
#include "core/array.h"
#include "core/os/memory.h"
@@ -61,7 +61,7 @@ void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_poo
memnew_placement(dest, Array);
dest->resize(pca->size());
- for (size_t i = 0; i < dest->size(); i++) {
+ for (int i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
dest->operator[](i) = v;
}
@@ -73,7 +73,7 @@ void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_p
memnew_placement(dest, Array);
dest->resize(pca->size());
- for (size_t i = 0; i < dest->size(); i++) {
+ for (int i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
dest->operator[](i) = v;
}
@@ -85,7 +85,7 @@ void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_p
memnew_placement(dest, Array);
dest->resize(pca->size());
- for (size_t i = 0; i < dest->size(); i++) {
+ for (int i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
dest->operator[](i) = v;
}
@@ -97,7 +97,7 @@ void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_po
memnew_placement(dest, Array);
dest->resize(pca->size());
- for (size_t i = 0; i < dest->size(); i++) {
+ for (int i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
dest->operator[](i) = v;
}
@@ -109,7 +109,7 @@ void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool
memnew_placement(dest, Array);
dest->resize(pca->size());
- for (size_t i = 0; i < dest->size(); i++) {
+ for (int i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
dest->operator[](i) = v;
}
@@ -121,7 +121,7 @@ void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_
memnew_placement(dest, Array);
dest->resize(pca->size());
- for (size_t i = 0; i < dest->size(); i++) {
+ for (int i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
dest->operator[](i) = v;
}
@@ -133,7 +133,7 @@ void GDAPI godot_array_new_pool_byte_array(godot_array *r_dest, const godot_pool
memnew_placement(dest, Array);
dest->resize(pca->size());
- for (size_t i = 0; i < dest->size(); i++) {
+ for (int i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
dest->operator[](i) = v;
}
diff --git a/modules/gdnative/godot/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index 8433355c12..b1327cdaef 100644
--- a/modules/gdnative/godot/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/basis.h>
+#include "gdnative/basis.h"
#include "core/math/matrix3.h"
#include "core/variant.h"
@@ -107,24 +107,6 @@ godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vect
return dest;
}
-void GDAPI godot_basis_set_scale(godot_basis *p_self, const godot_vector3 *p_scale) {
- Basis *self = (Basis *)p_self;
- const Vector3 *scale = (const Vector3 *)p_scale;
- self->set_scale(*scale);
-}
-
-void GDAPI godot_basis_set_rotation_euler(godot_basis *p_self, const godot_vector3 *p_euler) {
- Basis *self = (Basis *)p_self;
- const Vector3 *euler = (const Vector3 *)p_euler;
- self->set_rotation_euler(*euler);
-}
-
-void GDAPI godot_basis_set_rotation_axis_angle(godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_angle) {
- Basis *self = (Basis *)p_self;
- const Vector3 *axis = (const Vector3 *)p_axis;
- self->set_rotation_axis_angle(*axis, p_angle);
-}
-
godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self) {
godot_vector3 dest;
const Basis *self = (const Basis *)p_self;
diff --git a/modules/gdnative/godot/color.cpp b/modules/gdnative/gdnative/color.cpp
index 3677fdc265..3f8912d896 100644
--- a/modules/gdnative/godot/color.cpp
+++ b/modules/gdnative/gdnative/color.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/color.h>
+#include "gdnative/color.h"
#include "core/color.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp
index 2996cc78a3..ed98cdbb00 100644
--- a/modules/gdnative/godot/dictionary.cpp
+++ b/modules/gdnative/gdnative/dictionary.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/dictionary.h>
+#include "gdnative/dictionary.h"
#include "core/variant.h"
// core/variant.h before to avoid compile errors with MSVC
diff --git a/modules/gdnative/godot/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 7cd52da34d..cf1f6a4f16 100644
--- a/modules/gdnative/godot/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -27,11 +27,10 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/gdnative.h>
+#include "gdnative/gdnative.h"
#include "class_db.h"
#include "error_macros.h"
-#include "gdnative.h"
#include "global_constants.h"
#include "os/os.h"
#include "project_settings.h"
diff --git a/modules/gdnative/godot/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp
index 2309588a81..50fade5b94 100644
--- a/modules/gdnative/godot/node_path.cpp
+++ b/modules/gdnative/gdnative/node_path.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/node_path.h>
+#include "gdnative/node_path.h"
#include "core/node_path.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/plane.cpp b/modules/gdnative/gdnative/plane.cpp
index f3d4b6971e..a5e05ffa6b 100644
--- a/modules/gdnative/godot/plane.cpp
+++ b/modules/gdnative/gdnative/plane.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/plane.h>
+#include "gdnative/plane.h"
#include "core/math/plane.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp
index 2e533077f6..1393374da2 100644
--- a/modules/gdnative/godot/pool_arrays.cpp
+++ b/modules/gdnative/gdnative/pool_arrays.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/pool_arrays.h>
+#include "gdnative/pool_arrays.h"
#include "array.h"
#include "core/variant.h"
@@ -65,7 +65,7 @@ void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *r_dest, c
memnew_placement(dest, PoolVector<uint8_t>);
dest->resize(a->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (int i = 0; i < a->size(); i++) {
dest->set(i, (*a)[i]);
}
}
@@ -144,7 +144,7 @@ void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *r_dest, con
memnew_placement(dest, PoolVector<godot_int>);
dest->resize(a->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (int i = 0; i < a->size(); i++) {
dest->set(i, (*a)[i]);
}
}
@@ -223,7 +223,7 @@ void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *r_dest, c
memnew_placement(dest, PoolVector<godot_real>);
dest->resize(a->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (int i = 0; i < a->size(); i++) {
dest->set(i, (*a)[i]);
}
}
@@ -302,7 +302,7 @@ void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *r_des
memnew_placement(dest, PoolVector<String>);
dest->resize(a->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (int i = 0; i < a->size(); i++) {
dest->set(i, (*a)[i]);
}
}
@@ -389,7 +389,7 @@ void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *r_d
memnew_placement(dest, PoolVector<Vector2>);
dest->resize(a->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (int i = 0; i < a->size(); i++) {
dest->set(i, (*a)[i]);
}
}
@@ -475,7 +475,7 @@ void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *r_d
memnew_placement(dest, PoolVector<Vector3>);
dest->resize(a->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (int i = 0; i < a->size(); i++) {
dest->set(i, (*a)[i]);
}
}
@@ -561,7 +561,7 @@ void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *r_dest,
memnew_placement(dest, PoolVector<Color>);
dest->resize(a->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (int i = 0; i < a->size(); i++) {
dest->set(i, (*a)[i]);
}
}
diff --git a/modules/gdnative/godot/quat.cpp b/modules/gdnative/gdnative/quat.cpp
index e6bea78b60..7db7847da1 100644
--- a/modules/gdnative/godot/quat.cpp
+++ b/modules/gdnative/gdnative/quat.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/quat.h>
+#include "gdnative/quat.h"
#include "core/math/quat.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp
index 98e7855dc9..ecd8cce9ca 100644
--- a/modules/gdnative/godot/rect2.cpp
+++ b/modules/gdnative/gdnative/rect2.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/rect2.h>
+#include "gdnative/rect2.h"
#include "core/math/math_2d.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/rect3.cpp b/modules/gdnative/gdnative/rect3.cpp
index 88952ab49c..d34d964db9 100644
--- a/modules/gdnative/godot/rect3.cpp
+++ b/modules/gdnative/gdnative/rect3.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/rect3.h>
+#include "gdnative/rect3.h"
#include "core/math/rect3.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/rid.cpp b/modules/gdnative/gdnative/rid.cpp
index 51c8aaa1b3..f05c39906c 100644
--- a/modules/gdnative/godot/rid.cpp
+++ b/modules/gdnative/gdnative/rid.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/rid.h>
+#include "gdnative/rid.h"
#include "core/resource.h"
#include "core/rid.h"
diff --git a/modules/gdnative/godot/string.cpp b/modules/gdnative/gdnative/string.cpp
index 3790b6ea95..9b715ce36a 100644
--- a/modules/gdnative/godot/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/string.h>
+#include "gdnative/string.h"
#include "core/variant.h"
#include "string_db.h"
@@ -232,7 +232,7 @@ godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string
return self->findn(*what, p_from);
}
-godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what) {
+godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what) {
const String *self = (const String *)p_self;
String *what = (String *)&p_what;
diff --git a/modules/gdnative/godot/transform.cpp b/modules/gdnative/gdnative/transform.cpp
index a965067b77..d7a3e78d3f 100644
--- a/modules/gdnative/godot/transform.cpp
+++ b/modules/gdnative/gdnative/transform.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/transform.h>
+#include "gdnative/transform.h"
#include "core/math/transform.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp
index 9fc44ecdfa..dcb54f7a53 100644
--- a/modules/gdnative/godot/transform2d.cpp
+++ b/modules/gdnative/gdnative/transform2d.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/transform2d.h>
+#include "gdnative/transform2d.h"
#include "core/math/math_2d.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/variant.cpp b/modules/gdnative/gdnative/variant.cpp
index 582544b3a0..b61f80b1f9 100644
--- a/modules/gdnative/godot/variant.cpp
+++ b/modules/gdnative/gdnative/variant.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/variant.h>
+#include "gdnative/variant.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index 78ed5f06a9..67f858997f 100644
--- a/modules/gdnative/godot/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/vector2.h>
+#include "gdnative/vector2.h"
#include "core/math/math_2d.h"
#include "core/variant.h"
diff --git a/modules/gdnative/godot/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index 5faeac2864..c85a3f1c08 100644
--- a/modules/gdnative/godot/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <godot/vector3.h>
+#include "gdnative/vector3.h"
#include "core/variant.h"
#include "core/vector.h"
diff --git a/modules/gdnative/godot/icon.png.import b/modules/gdnative/godot/icon.png.import
deleted file mode 100644
index 27920124f9..0000000000
--- a/modules/gdnative/godot/icon.png.import
+++ /dev/null
@@ -1,23 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/icon.png-aa47d037a37fb38b3b7e7828e4eec407.stex"
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-stream=false
-size_limit=0
-detect_3d=true
diff --git a/modules/gdnative/godot/array.h b/modules/gdnative/include/gdnative/array.h
index 434ce958c9..edab028cba 100644
--- a/modules/gdnative/godot/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -37,7 +37,7 @@ extern "C" {
#include <stdint.h>
-#define GODOT_ARRAY_SIZE 8
+#define GODOT_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED
@@ -46,10 +46,10 @@ typedef struct {
} godot_array;
#endif
-#include <godot/pool_arrays.h>
-#include <godot/variant.h>
+#include <gdnative/pool_arrays.h>
+#include <gdnative/variant.h>
-#include <godot/gdnative.h>
+#include <gdnative/gdnative.h>
void GDAPI godot_array_new(godot_array *r_dest);
void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src);
diff --git a/modules/gdnative/godot/basis.h b/modules/gdnative/include/gdnative/basis.h
index d336bb9bc1..8ff6a6f541 100644
--- a/modules/gdnative/godot/basis.h
+++ b/modules/gdnative/include/gdnative/basis.h
@@ -45,9 +45,9 @@ typedef struct {
} godot_basis;
#endif
-#include <godot/gdnative.h>
-#include <godot/quat.h>
-#include <godot/vector3.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/quat.h>
+#include <gdnative/vector3.h>
void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis);
void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi);
@@ -67,12 +67,6 @@ godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vec
godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale);
-void GDAPI godot_basis_set_scale(godot_basis *p_self, const godot_vector3 *p_scale);
-
-void GDAPI godot_basis_set_rotation_euler(godot_basis *p_self, const godot_vector3 *p_euler);
-
-void GDAPI godot_basis_set_rotation_axis_angle(godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_angle);
-
godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self);
godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self);
diff --git a/modules/gdnative/godot/color.h b/modules/gdnative/include/gdnative/color.h
index 5d550e40b3..90dccf75aa 100644
--- a/modules/gdnative/godot/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -45,8 +45,8 @@ typedef struct {
} godot_color;
#endif
-#include <godot/gdnative.h>
-#include <godot/string.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/string.h>
void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a);
void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b);
diff --git a/modules/gdnative/godot/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h
index bbe40f23c3..c85c3f3830 100644
--- a/modules/gdnative/godot/dictionary.h
+++ b/modules/gdnative/include/gdnative/dictionary.h
@@ -36,7 +36,7 @@ extern "C" {
#include <stdint.h>
-#define GODOT_DICTIONARY_SIZE 8
+#define GODOT_DICTIONARY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED
@@ -45,9 +45,9 @@ typedef struct {
} godot_dictionary;
#endif
-#include <godot/array.h>
-#include <godot/gdnative.h>
-#include <godot/variant.h>
+#include <gdnative/array.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/variant.h>
void GDAPI godot_dictionary_new(godot_dictionary *r_dest);
void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src);
diff --git a/modules/gdnative/godot/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 8b289da1f5..c574c56d5a 100644
--- a/modules/gdnative/godot/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -56,7 +56,7 @@ extern "C" {
#define GDAPI GDCALLINGCONV
#endif
#else
-#define GDCALLINGCONV __attribute__((sysv_abi))
+#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default")))
#define GDAPI GDCALLINGCONV
#endif
@@ -146,100 +146,74 @@ typedef float godot_real;
/////// Object (forward declared)
typedef void godot_object;
-/////// Brute force forward declarations for the rest
-/*
-typedef struct godot_variant godot_variant;
-typedef struct godot_string godot_string;
-typedef struct godot_vector2 godot_vector2;
-typedef struct godot_rect2 godot_rect2;
-typedef struct godot_vector3 godot_vector3;
-typedef struct godot_transform2d godot_transform2d;
-typedef struct godot_plane godot_plane;
-typedef struct godot_quat godot_quat;
-typedef struct godot_rect3 godot_rect3;
-typedef struct godot_basis godot_basis;
-typedef struct godot_transform godot_transform;
-typedef struct godot_color godot_color;
-typedef struct godot_node_path godot_node_path;
-typedef struct godot_rid godot_rid;
-typedef struct godot_dictionary godot_dictionary;
-typedef struct godot_array godot_array;
-typedef struct godot_pool_byte_array godot_pool_byte_array;
-typedef struct godot_pool_int_array godot_pool_int_array;
-typedef struct godot_pool_real_array godot_pool_real_array;
-typedef struct godot_pool_string_array godot_pool_string_array;
-typedef struct godot_pool_vector2_array godot_pool_vector2_array;
-typedef struct godot_pool_vector3_array godot_pool_vector3_array;
-typedef struct godot_pool_color_array godot_pool_color_array;
-*/
/////// String
-#include <godot/string.h>
+#include <gdnative/string.h>
////// Vector2
-#include <godot/vector2.h>
+#include <gdnative/vector2.h>
////// Rect2
-#include <godot/rect2.h>
+#include <gdnative/rect2.h>
////// Vector3
-#include <godot/vector3.h>
+#include <gdnative/vector3.h>
////// Transform2D
-#include <godot/transform2d.h>
+#include <gdnative/transform2d.h>
/////// Plane
-#include <godot/plane.h>
+#include <gdnative/plane.h>
/////// Quat
-#include <godot/quat.h>
+#include <gdnative/quat.h>
/////// Rect3
-#include <godot/rect3.h>
+#include <gdnative/rect3.h>
/////// Basis
-#include <godot/basis.h>
+#include <gdnative/basis.h>
/////// Transform
-#include <godot/transform.h>
+#include <gdnative/transform.h>
/////// Color
-#include <godot/color.h>
+#include <gdnative/color.h>
/////// NodePath
-#include <godot/node_path.h>
+#include <gdnative/node_path.h>
/////// RID
-#include <godot/rid.h>
+#include <gdnative/rid.h>
/////// Dictionary
-#include <godot/dictionary.h>
+#include <gdnative/dictionary.h>
/////// Array
-#include <godot/array.h>
+#include <gdnative/array.h>
// single API file for Pool*Array
-#include <godot/pool_arrays.h>
+#include <gdnative/pool_arrays.h>
void GDAPI godot_object_destroy(godot_object *p_o);
////// Variant
-#include <godot/variant.h>
+#include <gdnative/variant.h>
////// Singleton API
diff --git a/modules/gdnative/godot/node_path.h b/modules/gdnative/include/gdnative/node_path.h
index 3e2a99e461..0cfdbc1127 100644
--- a/modules/gdnative/godot/node_path.h
+++ b/modules/gdnative/include/gdnative/node_path.h
@@ -36,7 +36,7 @@ extern "C" {
#include <stdint.h>
-#define GODOT_NODE_PATH_SIZE 8
+#define GODOT_NODE_PATH_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED
@@ -45,8 +45,8 @@ typedef struct {
} godot_node_path;
#endif
-#include <godot/gdnative.h>
-#include <godot/string.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/string.h>
void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from);
void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src);
diff --git a/modules/gdnative/godot/plane.h b/modules/gdnative/include/gdnative/plane.h
index 27548c8b0c..6a8915e08b 100644
--- a/modules/gdnative/godot/plane.h
+++ b/modules/gdnative/include/gdnative/plane.h
@@ -45,8 +45,8 @@ typedef struct {
} godot_plane;
#endif
-#include <godot/gdnative.h>
-#include <godot/vector3.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/vector3.h>
void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d);
void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3);
diff --git a/modules/gdnative/godot/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h
index ecd85ddfe8..cb1095ee8c 100644
--- a/modules/gdnative/godot/pool_arrays.h
+++ b/modules/gdnative/include/gdnative/pool_arrays.h
@@ -38,7 +38,7 @@ extern "C" {
/////// PoolByteArray
-#define GODOT_POOL_BYTE_ARRAY_SIZE 8
+#define GODOT_POOL_BYTE_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED
@@ -49,7 +49,7 @@ typedef struct {
/////// PoolIntArray
-#define GODOT_POOL_INT_ARRAY_SIZE 8
+#define GODOT_POOL_INT_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED
@@ -60,7 +60,7 @@ typedef struct {
/////// PoolRealArray
-#define GODOT_POOL_REAL_ARRAY_SIZE 8
+#define GODOT_POOL_REAL_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED
@@ -71,7 +71,7 @@ typedef struct {
/////// PoolStringArray
-#define GODOT_POOL_STRING_ARRAY_SIZE 8
+#define GODOT_POOL_STRING_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED
@@ -82,7 +82,7 @@ typedef struct {
/////// PoolVector2Array
-#define GODOT_POOL_VECTOR2_ARRAY_SIZE 8
+#define GODOT_POOL_VECTOR2_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED
@@ -93,7 +93,7 @@ typedef struct {
/////// PoolVector3Array
-#define GODOT_POOL_VECTOR3_ARRAY_SIZE 8
+#define GODOT_POOL_VECTOR3_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED
@@ -104,7 +104,7 @@ typedef struct {
/////// PoolColorArray
-#define GODOT_POOL_COLOR_ARRAY_SIZE 8
+#define GODOT_POOL_COLOR_ARRAY_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED
@@ -113,12 +113,12 @@ typedef struct {
} godot_pool_color_array;
#endif
-#include <godot/array.h>
-#include <godot/color.h>
-#include <godot/vector2.h>
-#include <godot/vector3.h>
+#include <gdnative/array.h>
+#include <gdnative/color.h>
+#include <gdnative/vector2.h>
+#include <gdnative/vector3.h>
-#include <godot/gdnative.h>
+#include <gdnative/gdnative.h>
// byte
diff --git a/modules/gdnative/godot/quat.h b/modules/gdnative/include/gdnative/quat.h
index 9a3238a337..4ffb96eb26 100644
--- a/modules/gdnative/godot/quat.h
+++ b/modules/gdnative/include/gdnative/quat.h
@@ -45,8 +45,8 @@ typedef struct {
} godot_quat;
#endif
-#include <godot/gdnative.h>
-#include <godot/vector3.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/vector3.h>
void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w);
void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle);
diff --git a/modules/gdnative/godot/rect2.h b/modules/gdnative/include/gdnative/rect2.h
index 8ceeddf1b4..9e6cf60342 100644
--- a/modules/gdnative/godot/rect2.h
+++ b/modules/gdnative/include/gdnative/rect2.h
@@ -43,8 +43,8 @@ typedef struct godot_rect2 {
} godot_rect2;
#endif
-#include <godot/gdnative.h>
-#include <godot/vector2.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/vector2.h>
void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size);
void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height);
diff --git a/modules/gdnative/godot/rect3.h b/modules/gdnative/include/gdnative/rect3.h
index ca96aadd5c..f94b6fea25 100644
--- a/modules/gdnative/godot/rect3.h
+++ b/modules/gdnative/include/gdnative/rect3.h
@@ -45,9 +45,9 @@ typedef struct {
} godot_rect3;
#endif
-#include <godot/gdnative.h>
-#include <godot/plane.h>
-#include <godot/vector3.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/plane.h>
+#include <gdnative/vector3.h>
void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size);
diff --git a/modules/gdnative/godot/rid.h b/modules/gdnative/include/gdnative/rid.h
index b685157cec..d9b5336fc9 100644
--- a/modules/gdnative/godot/rid.h
+++ b/modules/gdnative/include/gdnative/rid.h
@@ -36,7 +36,7 @@ extern "C" {
#include <stdint.h>
-#define GODOT_RID_SIZE 8
+#define GODOT_RID_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
@@ -45,7 +45,7 @@ typedef struct {
} godot_rid;
#endif
-#include <godot/gdnative.h>
+#include <gdnative/gdnative.h>
void GDAPI godot_rid_new(godot_rid *r_dest);
diff --git a/modules/gdnative/godot/string.h b/modules/gdnative/include/gdnative/string.h
index f41626faa1..aca23a81d8 100644
--- a/modules/gdnative/godot/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -37,7 +37,7 @@ extern "C" {
#include <stdint.h>
#include <wchar.h>
-#define GODOT_STRING_SIZE 8
+#define GODOT_STRING_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
@@ -46,8 +46,8 @@ typedef struct {
} godot_string;
#endif
-#include <godot/gdnative.h>
-#include <godot/variant.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/variant.h>
void GDAPI godot_string_new(godot_string *r_dest);
void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src);
@@ -82,7 +82,7 @@ godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot
godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key);
godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what);
godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
-godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what);
+godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what);
godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values);
godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder);
godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len);
diff --git a/modules/gdnative/godot/transform.h b/modules/gdnative/include/gdnative/transform.h
index 60788e3d57..656afae129 100644
--- a/modules/gdnative/godot/transform.h
+++ b/modules/gdnative/include/gdnative/transform.h
@@ -45,10 +45,10 @@ typedef struct {
} godot_transform;
#endif
-#include <godot/basis.h>
-#include <godot/gdnative.h>
-#include <godot/variant.h>
-#include <godot/vector3.h>
+#include <gdnative/basis.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/variant.h>
+#include <gdnative/vector3.h>
void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin);
void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin);
diff --git a/modules/gdnative/godot/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h
index c0f5725eed..a945868b17 100644
--- a/modules/gdnative/godot/transform2d.h
+++ b/modules/gdnative/include/gdnative/transform2d.h
@@ -45,9 +45,9 @@ typedef struct {
} godot_transform2d;
#endif
-#include <godot/gdnative.h>
-#include <godot/variant.h>
-#include <godot/vector2.h>
+#include <gdnative/gdnative.h>
+#include <gdnative/variant.h>
+#include <gdnative/vector2.h>
void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos);
void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin);
diff --git a/modules/gdnative/godot/variant.h b/modules/gdnative/include/gdnative/variant.h
index fda24db8d4..969506585d 100644
--- a/modules/gdnative/godot/variant.h
+++ b/modules/gdnative/include/gdnative/variant.h
@@ -36,7 +36,7 @@ extern "C" {
#include <stdint.h>
-#define GODOT_VARIANT_SIZE 24
+#define GODOT_VARIANT_SIZE (16 + sizeof(void *))
#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
@@ -99,25 +99,25 @@ typedef struct godot_variant_call_error {
godot_variant_type expected;
} godot_variant_call_error;
-#include <godot/array.h>
-#include <godot/basis.h>
-#include <godot/color.h>
-#include <godot/dictionary.h>
-#include <godot/node_path.h>
-#include <godot/plane.h>
-#include <godot/pool_arrays.h>
-#include <godot/quat.h>
-#include <godot/rect2.h>
-#include <godot/rect3.h>
-#include <godot/rid.h>
-#include <godot/string.h>
-#include <godot/transform.h>
-#include <godot/transform2d.h>
-#include <godot/variant.h>
-#include <godot/vector2.h>
-#include <godot/vector3.h>
-
-#include <godot/gdnative.h>
+#include <gdnative/array.h>
+#include <gdnative/basis.h>
+#include <gdnative/color.h>
+#include <gdnative/dictionary.h>
+#include <gdnative/node_path.h>
+#include <gdnative/plane.h>
+#include <gdnative/pool_arrays.h>
+#include <gdnative/quat.h>
+#include <gdnative/rect2.h>
+#include <gdnative/rect3.h>
+#include <gdnative/rid.h>
+#include <gdnative/string.h>
+#include <gdnative/transform.h>
+#include <gdnative/transform2d.h>
+#include <gdnative/variant.h>
+#include <gdnative/vector2.h>
+#include <gdnative/vector3.h>
+
+#include <gdnative/gdnative.h>
godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v);
diff --git a/modules/gdnative/godot/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 98e9700e32..0af4abae27 100644
--- a/modules/gdnative/godot/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -45,7 +45,7 @@ typedef struct {
} godot_vector2;
#endif
-#include <godot/gdnative.h>
+#include <gdnative/gdnative.h>
void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y);
diff --git a/modules/gdnative/godot/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index b76ca11a9c..a27d516ec5 100644
--- a/modules/gdnative/godot/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -45,8 +45,8 @@ typedef struct {
} godot_vector3;
#endif
-#include <godot/basis.h>
-#include <godot/gdnative.h>
+#include <gdnative/basis.h>
+#include <gdnative/gdnative.h>
typedef enum {
GODOT_VECTOR3_AXIS_X,
diff --git a/modules/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index 1eaf459570..96f213ead7 100644
--- a/modules/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot.h */
+/* godot_nativescript.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,7 +30,7 @@
#ifndef GODOT_NATIVESCRIPT_H
#define GODOT_NATIVESCRIPT_H
-#include <godot/gdnative.h>
+#include <gdnative/gdnative.h>
#ifdef __cplusplus
extern "C" {
@@ -58,7 +58,7 @@ extern "C" {
#define GDAPI GDCALLINGCONV
#endif
#else
-#define GDCALLINGCONV __attribute__((sysv_abi))
+#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default")))
#define GDAPI GDCALLINGCONV
#endif
diff --git a/modules/nativescript/SCsub b/modules/gdnative/nativescript/SCsub
index e980e40e8e..e980e40e8e 100644
--- a/modules/nativescript/SCsub
+++ b/modules/gdnative/nativescript/SCsub
diff --git a/modules/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 4490197bdb..fdd5a2ea19 100644
--- a/modules/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -33,6 +33,7 @@
#include "class_db.h"
#include "core/global_constants.h"
+#include "core/pair.h"
#include "core/project_settings.h"
#include "os/file_access.h"
@@ -93,6 +94,11 @@ struct SignalAPI {
Map<int, Variant> default_arguments;
};
+struct EnumAPI {
+ String name;
+ List<Pair<int, String> > values;
+};
+
struct ClassAPI {
String class_name;
String super_class_name;
@@ -109,8 +115,28 @@ struct ClassAPI {
List<PropertyAPI> properties;
List<ConstantAPI> constants;
List<SignalAPI> signals_;
+ List<EnumAPI> enums;
};
+static String get_type_name(const PropertyInfo &info) {
+ if (info.type == Variant::INT && (info.usage & PROPERTY_USAGE_CLASS_IS_ENUM)) {
+ return String("enum.") + String(info.class_name).replace(".", "::");
+ }
+ if (info.class_name != StringName()) {
+ return info.class_name;
+ }
+ if (info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ return info.hint_string;
+ }
+ if (info.type == Variant::NIL && (info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) {
+ return "Variant";
+ }
+ if (info.type == Variant::NIL) {
+ return "void";
+ }
+ return Variant::get_type_name(info.type);
+}
+
/*
* Reads the entire Godot API to a list
*/
@@ -194,12 +220,8 @@ List<ClassAPI> generate_c_api_classes() {
if (argument.name.find(":") != -1) {
type = argument.name.get_slice(":", 1);
name = argument.name.get_slice(":", 0);
- } else if (argument.hint == PROPERTY_HINT_RESOURCE_TYPE) {
- type = argument.hint_string;
- } else if (argument.type == Variant::NIL) {
- type = "Variant";
} else {
- type = Variant::get_type_name(argument.type);
+ type = get_type_name(argument);
}
signal.argument_names.push_back(name);
@@ -233,12 +255,8 @@ List<ClassAPI> generate_c_api_classes() {
if (p->get().name.find(":") != -1) {
property_api.type = p->get().name.get_slice(":", 1);
property_api.name = p->get().name.get_slice(":", 0);
- } else if (p->get().hint == PROPERTY_HINT_RESOURCE_TYPE) {
- property_api.type = p->get().hint_string;
- } else if (p->get().type == Variant::NIL) {
- property_api.type = "Variant";
} else {
- property_api.type = Variant::get_type_name(p->get().type);
+ property_api.type = get_type_name(p->get());
}
if (!property_api.setter.empty() || !property_api.getter.empty()) {
@@ -260,17 +278,11 @@ List<ClassAPI> generate_c_api_classes() {
//method name
method_api.method_name = m->get().name;
//method return type
- if (method_bind && method_bind->get_return_type() != StringName()) {
- method_api.return_type = method_bind->get_return_type();
- } else if (method_api.method_name.find(":") != -1) {
+ if (method_api.method_name.find(":") != -1) {
method_api.return_type = method_api.method_name.get_slice(":", 1);
method_api.method_name = method_api.method_name.get_slice(":", 0);
- } else if (m->get().return_val.type != Variant::NIL) {
- method_api.return_type = m->get().return_val.hint == PROPERTY_HINT_RESOURCE_TYPE ? m->get().return_val.hint_string : Variant::get_type_name(m->get().return_val.type);
- } else if (m->get().return_val.name != "") {
- method_api.return_type = m->get().return_val.name;
} else {
- method_api.return_type = "void";
+ method_api.return_type = get_type_name(m->get().return_val);
}
method_api.argument_count = method_info.arguments.size();
@@ -321,6 +333,25 @@ List<ClassAPI> generate_c_api_classes() {
}
}
+ // enums
+ {
+ List<EnumAPI> enums;
+ List<StringName> enum_names;
+ ClassDB::get_enum_list(class_name, &enum_names, true);
+ for (List<StringName>::Element *E = enum_names.front(); E; E = E->next()) {
+ List<StringName> value_names;
+ EnumAPI enum_api;
+ enum_api.name = E->get();
+ ClassDB::get_enum_constants(class_name, E->get(), &value_names, true);
+ for (List<StringName>::Element *val_e = value_names.front(); val_e; val_e = val_e->next()) {
+ int int_val = ClassDB::get_integer_constant(class_name, val_e->get(), NULL);
+ enum_api.values.push_back(Pair<int, String>(int_val, val_e->get()));
+ }
+ enum_api.values.sort_custom<PairSort<int, String> >();
+ class_api.enums.push_back(enum_api);
+ }
+ }
+
api.push_back(class_api);
}
@@ -410,11 +441,24 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
source.push_back("\t\t\t\t]\n");
source.push_back(String("\t\t\t}") + (e->next() ? "," : "") + "\n");
}
+ source.push_back("\t\t],\n");
+
+ source.push_back("\t\t\"enums\": [\n");
+ for (List<EnumAPI>::Element *e = api.enums.front(); e; e = e->next()) {
+ source.push_back("\t\t\t{\n");
+ source.push_back("\t\t\t\t\"name\": \"" + e->get().name + "\",\n");
+ source.push_back("\t\t\t\t\"values\": {\n");
+ for (List<Pair<int, String> >::Element *val_e = e->get().values.front(); val_e; val_e = val_e->next()) {
+ source.push_back("\t\t\t\t\t\"" + val_e->get().second + "\": " + itos(val_e->get().first));
+ source.push_back(String((val_e->next() ? "," : "")) + "\n");
+ }
+ source.push_back("\t\t\t\t}\n");
+ source.push_back(String("\t\t\t}") + (e->next() ? "," : "") + "\n");
+ }
source.push_back("\t\t]\n");
source.push_back(String("\t}") + (c->next() ? "," : "") + "\n");
}
-
source.push_back("]");
return source;
diff --git a/modules/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h
index 56c2d786e6..56c2d786e6 100644
--- a/modules/nativescript/api_generator.h
+++ b/modules/gdnative/nativescript/api_generator.h
diff --git a/modules/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index 926b3261b2..61ac13b796 100644
--- a/modules/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -27,17 +27,17 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "godot_nativescript.h"
-
-#include "nativescript.h"
+#include "nativescript/godot_nativescript.h"
#include "class_db.h"
#include "error_macros.h"
-#include "gdnative.h"
+#include "gdnative/gdnative.h"
#include "global_constants.h"
#include "project_settings.h"
#include "variant.h"
+#include "nativescript.h"
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/modules/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 3799ce31f8..724b8390da 100644
--- a/modules/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "nativescript.h"
-#include "modules/gdnative/godot/gdnative.h"
+#include "gdnative/gdnative.h"
#include "global_constants.h"
#include "io/file_access_encrypted.h"
@@ -994,6 +994,8 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
#endif
// See if this library was "registered" already.
const String &lib_path = lib->get_active_library_path();
+ ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform");
+ ERR_FAIL_COND(lib_path.length() == 0);
Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path);
if (!E) {
diff --git a/modules/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index 571a3c9cc7..6c55e3e327 100644
--- a/modules/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -38,8 +38,8 @@
#include "script_language.h"
#include "self_list.h"
-#include "godot_nativescript.h"
#include "modules/gdnative/gdnative.h"
+#include <nativescript/godot_nativescript.h>
#ifndef NO_THREADS
#include "os/mutex.h"
diff --git a/modules/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp
index b846710ab8..b846710ab8 100644
--- a/modules/nativescript/register_types.cpp
+++ b/modules/gdnative/nativescript/register_types.cpp
diff --git a/modules/nativescript/register_types.h b/modules/gdnative/nativescript/register_types.h
index 7ac558f68f..7ac558f68f 100644
--- a/modules/nativescript/register_types.h
+++ b/modules/gdnative/nativescript/register_types.h
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 9ad05b7194..d809109987 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -28,12 +28,99 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_types.h"
+#include "gdnative/gdnative.h"
+
#include "gdnative.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
+#include "nativescript/register_types.h"
+
+#include "core/engine.h"
#include "core/os/os.h"
+#include "core/project_settings.h"
+
+#ifdef TOOLS_ENABLED
+#include "editor/editor_node.h"
+
+// Class used to discover singleton gdnative files
+
+void actual_discoverer_handler();
+
+class GDNativeSingletonDiscover : public Object {
+ // GDCLASS(GDNativeSingletonDiscover, Object)
+
+ virtual String get_class() const {
+ // okay, this is a really dirty hack.
+ // We're overriding get_class so we can connect it to a signal
+ // This works because get_class is a virtual method, so we don't
+ // need to register a new class to ClassDB just for this one
+ // little signal.
+
+ actual_discoverer_handler();
+
+ return "Object";
+ }
+};
+
+Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) {
+
+ Set<String> file_paths;
+
+ // check children
+
+ for (int i = 0; i < p_dir->get_file_count(); i++) {
+ String file_name = p_dir->get_file(i);
+ String file_type = p_dir->get_file_type(i);
+
+ if (file_type != "GDNativeLibrary") {
+ continue;
+ }
+
+ Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i));
+ if (lib.is_valid() && lib->is_singleton_gdnative()) {
+ file_paths.insert(p_dir->get_file_path(i));
+ }
+ }
+
+ // check subdirectories
+ for (int i = 0; i < p_dir->get_subdir_count(); i++) {
+ Set<String> paths = get_gdnative_singletons(p_dir->get_subdir(i));
+
+ for (Set<String>::Element *E = paths.front(); E; E = E->next()) {
+ file_paths.insert(E->get());
+ }
+ }
+
+ return file_paths;
+}
+
+void actual_discoverer_handler() {
+ EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->get_filesystem();
+
+ Set<String> file_paths = get_gdnative_singletons(dir);
+
+ Array files;
+ files.resize(file_paths.size());
+ int i = 0;
+ for (Set<String>::Element *E = file_paths.front(); E; i++, E = E->next()) {
+ files.set(i, E->get());
+ }
+
+ ProjectSettings::get_singleton()->set("gdnative/singletons", files);
+
+ ProjectSettings::get_singleton()->save();
+}
+
+GDNativeSingletonDiscover *discoverer = NULL;
+
+void discoverer_callback() {
+ discoverer = memnew(GDNativeSingletonDiscover);
+ EditorFileSystem::get_singleton()->connect("filesystem_changed", discoverer, "get_class");
+}
+
+#endif
godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot_array *p_args) {
if (handle == NULL) {
@@ -62,21 +149,110 @@ godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot
return proc(NULL, p_args);
}
+void cb_singleton_call(
+ void *p_handle,
+ godot_string *p_proc_name,
+ void *p_data,
+ int p_num_args,
+ void **p_args,
+ void *r_return) {
+ if (p_handle == NULL) {
+ ERR_PRINT("No valid library handle, can't call singleton procedure");
+ return;
+ }
+
+ void *singleton_proc;
+ Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
+ p_handle,
+ *(String *)p_proc_name,
+ singleton_proc);
+
+ if (err != OK) {
+ return;
+ }
+
+ void (*singleton_procedure_ptr)() = (void (*)())singleton_proc;
+ singleton_procedure_ptr();
+}
+
GDNativeCallRegistry *GDNativeCallRegistry::singleton;
+Vector<Ref<GDNative> > singleton_gdnatives;
+
void register_gdnative_types() {
+#ifdef TOOLS_ENABLED
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+ EditorNode::add_init_callback(discoverer_callback);
+ }
+#endif
+
ClassDB::register_class<GDNativeLibrary>();
ClassDB::register_class<GDNative>();
GDNativeCallRegistry::singleton = memnew(GDNativeCallRegistry);
GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall);
+
+ GDNativeCallRegistry::singleton->register_native_raw_call_type("gdnative_singleton_call", cb_singleton_call);
+
+ register_nativescript_types();
+
+ // run singletons
+
+ Array singletons = ProjectSettings::get_singleton()->get("gdnative/singletons");
+
+ singleton_gdnatives.resize(singletons.size());
+
+ for (int i = 0; i < singletons.size(); i++) {
+ String path = singletons[i];
+
+ Ref<GDNativeLibrary> lib = ResourceLoader::load(path);
+
+ singleton_gdnatives[i].instance();
+ singleton_gdnatives[i]->set_library(lib);
+
+ if (!singleton_gdnatives[i]->initialize()) {
+ // Can't initialize. Don't make a native_call then
+ continue;
+ }
+
+ singleton_gdnatives[i]->call_native_raw(
+ "gdnative_singleton_call",
+ "godot_gdnative_singleton",
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ }
}
void unregister_gdnative_types() {
+
+ for (int i = 0; i < singleton_gdnatives.size(); i++) {
+
+ if (singleton_gdnatives[i].is_null()) {
+ continue;
+ }
+
+ if (!singleton_gdnatives[i]->is_initialized()) {
+ continue;
+ }
+
+ singleton_gdnatives[i]->terminate();
+ }
+
+ unregister_nativescript_types();
+
memdelete(GDNativeCallRegistry::singleton);
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ memdelete(discoverer);
+ }
+#endif
+
// This is for printing out the sizes of the core types
/*
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index b10694ddfd..70e7da5748 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -297,23 +297,25 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const
//not really "functions", but..
{
MethodInfo mi;
- mi.name = "preload:Resource";
+ mi.name = "preload";
mi.arguments.push_back(PropertyInfo(Variant::STRING, "path"));
mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "Resource");
p_functions->push_back(mi);
}
{
MethodInfo mi;
- mi.name = "yield:GDFunctionState";
+ mi.name = "yield";
mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal"));
mi.default_arguments.push_back(Variant::NIL);
mi.default_arguments.push_back(Variant::STRING);
+ mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "GDFunctionState");
p_functions->push_back(mi);
}
{
MethodInfo mi;
mi.name = "assert";
+ mi.return_val.type = Variant::NIL;
mi.arguments.push_back(PropertyInfo(Variant::BOOL, "condition"));
p_functions->push_back(mi);
}
@@ -1901,11 +1903,11 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N
arghint += ", ";
else
arghint += " ";
- if (i == p_argidx) {
+ if (i == p_argidx || (mi.flags & METHOD_FLAG_VARARG && i > p_argidx)) {
arghint += String::chr(0xFFFF);
}
arghint += _get_visual_datatype(mi.arguments[i]) + " " + mi.arguments[i].name;
- if (i == p_argidx) {
+ if (i == p_argidx || (mi.flags & METHOD_FLAG_VARARG && i > p_argidx)) {
arghint += String::chr(0xFFFF);
}
}
diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp
index e6f65fe0c2..ddee7b2521 100644
--- a/modules/gdscript/gd_function.cpp
+++ b/modules/gdscript/gd_function.cpp
@@ -290,8 +290,8 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
#ifdef DEBUG_ENABLED
- uint64_t function_start_time;
- uint64_t function_call_time;
+ uint64_t function_start_time = 0;
+ uint64_t function_call_time = 0;
if (GDScriptLanguage::get_singleton()->profiling) {
function_start_time = OS::get_singleton()->get_ticks_usec();
@@ -691,7 +691,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#ifdef DEBUG_ENABLED
- uint64_t call_time;
+ uint64_t call_time = 0;
if (GDScriptLanguage::get_singleton()->profiling) {
call_time = OS::get_singleton()->get_ticks_usec();
@@ -1026,7 +1026,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
case OPCODE_ITERATE_BEGIN: {
- CHECK_SPACE(8); //space for this an regular iterate
+ CHECK_SPACE(8); //space for this a regular iterate
GET_VARIANT_PTR(counter, 1);
GET_VARIANT_PTR(container, 2);
diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp
index 3bd0ce3fab..f0cfdd6258 100644
--- a/modules/gdscript/gd_functions.cpp
+++ b/modules/gdscript/gd_functions.cpp
@@ -1572,43 +1572,49 @@ MethodInfo GDFunctions::get_info(Function p_func) {
} break;
case TEXT_STR: {
- MethodInfo mi("str", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "..."));
+ MethodInfo mi("str");
mi.return_val.type = Variant::STRING;
+ mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
case TEXT_PRINT: {
- MethodInfo mi("print", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "..."));
+ MethodInfo mi("print");
mi.return_val.type = Variant::NIL;
+ mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
case TEXT_PRINT_TABBED: {
- MethodInfo mi("printt", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "..."));
+ MethodInfo mi("printt");
mi.return_val.type = Variant::NIL;
+ mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
case TEXT_PRINT_SPACED: {
- MethodInfo mi("prints", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "..."));
+ MethodInfo mi("prints");
mi.return_val.type = Variant::NIL;
+ mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
case TEXT_PRINTERR: {
- MethodInfo mi("printerr", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "..."));
+ MethodInfo mi("printerr");
mi.return_val.type = Variant::NIL;
+ mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
case TEXT_PRINTRAW: {
- MethodInfo mi("printraw", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "..."));
+ MethodInfo mi("printraw");
mi.return_val.type = Variant::NIL;
+ mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
@@ -1620,8 +1626,9 @@ MethodInfo GDFunctions::get_info(Function p_func) {
} break;
case STR_TO_VAR: {
- MethodInfo mi("str2var:Variant", PropertyInfo(Variant::STRING, "string"));
+ MethodInfo mi(Variant::NIL, "str2var", PropertyInfo(Variant::STRING, "string"));
mi.return_val.type = Variant::NIL;
+ mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case VAR_TO_BYTES: {
@@ -1632,14 +1639,16 @@ MethodInfo GDFunctions::get_info(Function p_func) {
} break;
case BYTES_TO_VAR: {
- MethodInfo mi("bytes2var:Variant", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes"));
+ MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes"));
mi.return_val.type = Variant::NIL;
+ mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case GEN_RANGE: {
- MethodInfo mi("range", PropertyInfo(Variant::NIL, "..."));
+ MethodInfo mi("range");
mi.return_val.type = Variant::ARRAY;
+ mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
case RESOURCE_LOAD: {
@@ -1663,14 +1672,15 @@ MethodInfo GDFunctions::get_info(Function p_func) {
} break;
case VALIDATE_JSON: {
- MethodInfo mi("validate_json:Variant", PropertyInfo(Variant::STRING, "json"));
+ MethodInfo mi("validate_json", PropertyInfo(Variant::STRING, "json"));
mi.return_val.type = Variant::STRING;
return mi;
} break;
case PARSE_JSON: {
- MethodInfo mi("parse_json:Variant", PropertyInfo(Variant::STRING, "json"));
+ MethodInfo mi(Variant::NIL, "parse_json", PropertyInfo(Variant::STRING, "json"));
mi.return_val.type = Variant::NIL;
+ mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case TO_JSON: {
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index 072937a521..72c3f9612a 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -1284,7 +1284,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
if (expression[next_op + 1].is_op) {
// this is not invalid and can really appear
// but it becomes invalid anyway because no binary op
- // can be followed by an unary op in a valid combination,
+ // can be followed by a unary op in a valid combination,
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators after ternary if.");
@@ -1294,7 +1294,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
if (expression[next_op + 3].is_op) {
// this is not invalid and can really appear
// but it becomes invalid anyway because no binary op
- // can be followed by an unary op in a valid combination,
+ // can be followed by a unary op in a valid combination,
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators after ternary else.");
@@ -1331,7 +1331,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
if (expression[next_op + 1].is_op) {
// this is not invalid and can really appear
// but it becomes invalid anyway because no binary op
- // can be followed by an unary op in a valid combination,
+ // can be followed by a unary op in a valid combination,
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators.");
@@ -1857,7 +1857,7 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) {
tokenizer->advance(1);
break;
} else {
- _set_error("'..' pattern only allowed at the end of an dictionary pattern");
+ _set_error("'..' pattern only allowed at the end of a dictionary pattern");
return NULL;
}
}
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 6f05a4770b..5e1a8b19ac 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -389,7 +389,6 @@ public:
virtual bool can_inherit_from_file() { return true; }
virtual int find_function(const String &p_function, const String &p_code) const;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
- virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return OK; }
virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint);
#ifdef TOOLS_ENABLED
virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result);
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 0de2cf80ea..ced1c3ca12 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -155,7 +155,7 @@ void GridMap::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"));
p_list->push_back(PropertyInfo(Variant::NIL, "Cell", PROPERTY_HINT_NONE, "cell_", PROPERTY_USAGE_GROUP));
- p_list->push_back(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.01,16384,0.01"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR3, "cell_size"));
p_list->push_back(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1"));
p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_x"));
p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_y"));
@@ -184,6 +184,7 @@ Ref<MeshLibrary> GridMap::get_theme() const {
void GridMap::set_cell_size(const Vector3 &p_size) {
+ ERR_FAIL_COND(p_size.x < 0.001 || p_size.y < 0.001 || p_size.z < 0.001);
cell_size = p_size;
_recreate_octant_data();
}
@@ -395,8 +396,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
Map<int, List<Pair<Transform, IndexKey> > > multimesh_items;
- print_line("updating octant " + itos(p_key.x) + ", " + itos(p_key.y) + ", " + itos(p_key.z) + " cells: " + itos(g.cells.size()));
-
for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) {
ERR_CONTINUE(!cell_map.has(E->get()));
@@ -463,7 +462,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
//update multimeshes
for (Map<int, List<Pair<Transform, IndexKey> > >::Element *E = multimesh_items.front(); E; E = E->next()) {
- print_line("multimesh item " + itos(E->key()) + " transforms " + itos(E->get().size()));
Octant::MultimeshInstance mmi;
RID mm = VS::get_singleton()->multimesh_create();
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 6f0a13e07f..f6a76ad2a1 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -1159,14 +1159,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
outer_mat.instance();
outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.8));
- outer_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ outer_mat->set_on_top_of_alpha();
outer_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
outer_mat->set_line_width(3.0);
outer_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
selection_floor_mat.instance();
selection_floor_mat->set_albedo(Color(0.80, 0.80, 1.0, 1));
- selection_floor_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ selection_floor_mat->set_on_top_of_alpha();
selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
selection_floor_mat->set_line_width(3.0);
//selection_floor_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index d883b0f280..92d88207b3 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* image_loader_jpegd.cpp */
+/* image_loader_hdr.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index e6703dc142..569978d28d 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* image_loader_jpegd.h */
+/* image_loader_hdr.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/modules/nativescript/config.py b/modules/nativescript/config.py
deleted file mode 100644
index 4f89ca0d4c..0000000000
--- a/modules/nativescript/config.py
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-def can_build(platform):
- return False
-
-
-def configure(env):
- env.use_ptrcall = True
diff --git a/modules/openssl/SCsub b/modules/openssl/SCsub
index add7d4dcfc..eb3c0e64d8 100644
--- a/modules/openssl/SCsub
+++ b/modules/openssl/SCsub
@@ -655,7 +655,7 @@ if (env['builtin_openssl'] != 'no'):
env_openssl.add_source_files(env.modules_sources, thirdparty_sources)
- # FIXME: Clone the environment to make a env_openssl and not pollute the modules env
+ # FIXME: Clone the environment to make env_openssl and not pollute the modules env
thirdparty_include_paths = [
"",
"crypto",
diff --git a/modules/regex/SCsub b/modules/regex/SCsub
index 0882406761..2dfc2739e9 100644
--- a/modules/regex/SCsub
+++ b/modules/regex/SCsub
@@ -1,7 +1,53 @@
#!/usr/bin/env python
Import('env')
+Import('env_modules')
-env.add_source_files(env.modules_sources, "*.cpp")
+env_regex = env_modules.Clone()
+env_regex.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=0"])
+env_regex.add_source_files(env.modules_sources, "*.cpp")
-Export('env')
+if (env['builtin_pcre2'] != 'no'):
+ jit_blacklist = ['javascript']
+ thirdparty_dir = '#thirdparty/pcre2/src/'
+ thirdparty_flags = ['-DPCRE2_STATIC', '-DHAVE_CONFIG_H']
+ if 'platform' in env and env['platform'] not in jit_blacklist:
+ thirdparty_flags.append('-DSUPPORT_JIT')
+ thirdparty_sources = [
+ "pcre2_auto_possess.c",
+ "pcre2_chartables.c",
+ "pcre2_compile.c",
+ "pcre2_config.c",
+ "pcre2_context.c",
+ "pcre2_dfa_match.c",
+ "pcre2_error.c",
+ "pcre2_find_bracket.c",
+ "pcre2_jit_compile.c",
+ "pcre2_maketables.c",
+ "pcre2_match.c",
+ "pcre2_match_data.c",
+ "pcre2_newline.c",
+ "pcre2_ord2utf.c",
+ "pcre2_pattern_info.c",
+ "pcre2_serialize.c",
+ "pcre2_string_utils.c",
+ "pcre2_study.c",
+ "pcre2_substitute.c",
+ "pcre2_substring.c",
+ "pcre2_tables.c",
+ "pcre2_ucd.c",
+ "pcre2_valid_utf.c",
+ "pcre2_xclass.c",
+ ]
+ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+ env_regex.Append(CPPPATH=[thirdparty_dir])
+ env_regex.Append(CPPFLAGS=thirdparty_flags)
+ def pcre2_builtin(width):
+ env_pcre2 = env_modules.Clone()
+ env_pcre2["OBJSUFFIX"] = "_" + width + env_pcre2["OBJSUFFIX"]
+ env_pcre2.Append(CPPPATH=[thirdparty_dir])
+ env_pcre2.add_source_files(env.modules_sources, thirdparty_sources)
+ env_pcre2.Append(CPPFLAGS=thirdparty_flags)
+ env_pcre2.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=" + width])
+ pcre2_builtin("16")
+ pcre2_builtin("32")
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp
index de0a6b7e21..00e8ce0f54 100644
--- a/modules/regex/regex.cpp
+++ b/modules/regex/regex.cpp
@@ -29,1479 +29,469 @@
/*************************************************************************/
#include "regex.h"
-#include <wchar.h>
-#include <wctype.h>
-
-static int RegEx_hex2int(const CharType c) {
- if ('0' <= c && c <= '9')
- return int(c - '0');
- else if ('a' <= c && c <= 'f')
- return int(c - 'a') + 10;
- else if ('A' <= c && c <= 'F')
- return int(c - 'A') + 10;
- return -1;
-}
-
-struct RegExSearch {
-
- Ref<RegExMatch> match;
- const CharType *str;
- int end;
- int eof;
-
- // For standard quantifier behaviour, test_parent is used to check the
- // rest of the pattern. If the pattern matches, to prevent the parent
- // from testing again, the complete flag is used as a shortcut out.
- bool complete;
-
- // With lookahead, the position needs to rewind to its starting position
- // when test_parent is used. Due to functional programming, this state
- // has to be kept as a parameter.
- Vector<int> lookahead_pos;
-
- CharType at(int p_pos) {
- return str[p_pos];
- }
-
- RegExSearch(Ref<RegExMatch> &p_match, int p_end, int p_lookahead)
- : match(p_match) {
-
- str = p_match->string.c_str();
- end = p_end;
- eof = p_match->string.length();
- complete = false;
- lookahead_pos.resize(p_lookahead);
- }
-};
-
-struct RegExNode {
-
- RegExNode *next;
- RegExNode *previous;
- RegExNode *parent;
- bool quantifiable;
- int length;
-
- RegExNode() {
-
- next = NULL;
- previous = NULL;
- parent = NULL;
- quantifiable = false;
- length = -1;
- }
-
- virtual ~RegExNode() {
-
- if (next)
- memdelete(next);
- }
+#include "core/os/memory.h"
- // For avoiding RTTI
- virtual bool is_look_behind() { return false; }
-
- virtual int test(RegExSearch &s, int pos) const {
-
- return next ? next->test(s, pos) : -1;
- }
-
- virtual int test_parent(RegExSearch &s, int pos) const {
-
- if (next)
- pos = next->test(s, pos);
-
- if (pos >= 0) {
- s.complete = true;
- if (parent)
- pos = parent->test_parent(s, pos);
- }
-
- if (pos < 0)
- s.complete = false;
-
- return pos;
- }
-
- void increment_length(int amount, bool subtract = false) {
-
- if (amount >= 0 && length >= 0) {
- if (!subtract)
- length += amount;
- else
- length -= amount;
- } else {
- length = -1;
- }
+extern "C" {
+#include <pcre2.h>
+}
- if (parent)
- parent->increment_length(amount, subtract);
- }
-};
+static void *_regex_malloc(PCRE2_SIZE size, void *user) {
-struct RegExNodeChar : public RegExNode {
+ return memalloc(size);
+}
- CharType ch;
+static void _regex_free(void *ptr, void *user) {
- RegExNodeChar(CharType p_char) {
+ memfree(ptr);
+}
- length = 1;
- quantifiable = true;
- ch = p_char;
- }
+int RegExMatch::_find(const Variant &p_name) const {
- virtual int test(RegExSearch &s, int pos) const {
+ if (p_name.is_num()) {
- if (s.end <= pos || 0 > pos || s.at(pos) != ch)
+ int i = (int)p_name;
+ if (i >= data.size())
return -1;
+ return i;
- return next ? next->test(s, pos + 1) : pos + 1;
- }
+ } else if (p_name.get_type() == Variant::STRING) {
- static CharType parse_escape(const CharType *&c) {
-
- int point = 0;
- switch (c[1]) {
- case 'x':
- for (int i = 2; i <= 3; ++i) {
- int res = RegEx_hex2int(c[i]);
- if (res == -1)
- return '\0';
- point = (point << 4) + res;
- }
- c = &c[3];
- return CharType(point);
- case 'u':
- for (int i = 2; i <= 5; ++i) {
- int res = RegEx_hex2int(c[i]);
- if (res == -1)
- return '\0';
- point = (point << 4) + res;
- }
- c = &c[5];
- return CharType(point);
- case '0': ++c; return '\0';
- case 'a': ++c; return '\a';
- case 'e': ++c; return '\e';
- case 'f': ++c; return '\f';
- case 'n': ++c; return '\n';
- case 'r': ++c; return '\r';
- case 't': ++c; return '\t';
- case 'v': ++c; return '\v';
- case 'b': ++c; return '\b';
- default: break;
- }
- return (++c)[0];
+ const Map<String, int>::Element *found = names.find((String)p_name);
+ if (found)
+ return found->value();
}
-};
-struct RegExNodeRange : public RegExNode {
+ return -1;
+}
- CharType start;
- CharType end;
+String RegExMatch::get_subject() const {
- RegExNodeRange(CharType p_start, CharType p_end) {
+ return subject;
+}
- length = 1;
- quantifiable = true;
- start = p_start;
- end = p_end;
- }
+int RegExMatch::get_group_count() const {
- virtual int test(RegExSearch &s, int pos) const {
+ if (data.size() == 0)
+ return 0;
+ return data.size() - 1;
+}
- if (s.end <= pos || 0 > pos)
- return -1;
+Dictionary RegExMatch::get_names() const {
- CharType c = s.at(pos);
- if (c < start || end < c)
- return -1;
+ Dictionary result;
- return next ? next->test(s, pos + 1) : pos + 1;
+ for (const Map<String, int>::Element *i = names.front(); i != NULL; i = i->next()) {
+ result[i->key()] = i->value();
}
-};
-
-struct RegExNodeShorthand : public RegExNode {
- CharType repr;
+ return result;
+}
- RegExNodeShorthand(CharType p_repr) {
+Array RegExMatch::get_strings() const {
- length = 1;
- quantifiable = true;
- repr = p_repr;
- }
+ Array result;
- virtual int test(RegExSearch &s, int pos) const {
+ int size = data.size();
- if (s.end <= pos || 0 > pos)
- return -1;
+ for (int i = 0; i < size; i++) {
- bool found = false;
- bool invert = false;
- CharType c = s.at(pos);
- switch (repr) {
- case '.':
- found = true;
- break;
- case 'W':
- invert = true;
- case 'w':
- found = (c == '_' || iswalnum(c) != 0);
- break;
- case 'D':
- invert = true;
- case 'd':
- found = ('0' <= c && c <= '9');
- break;
- case 'S':
- invert = true;
- case 's':
- found = (iswspace(c) != 0);
- break;
- default:
- break;
- }
+ int start = data[i].start;
- if (found == invert)
- return -1;
-
- return next ? next->test(s, pos + 1) : pos + 1;
- }
-};
-
-struct RegExNodeClass : public RegExNode {
-
- enum Type {
- Type_none,
- Type_alnum,
- Type_alpha,
- Type_ascii,
- Type_blank,
- Type_cntrl,
- Type_digit,
- Type_graph,
- Type_lower,
- Type_print,
- Type_punct,
- Type_space,
- Type_upper,
- Type_xdigit,
- Type_word
- };
-
- Type type;
-
- bool test_class(CharType c) const {
-
- static Vector<CharType> REGEX_NODE_SPACE = String(" \t\r\n\f");
- static Vector<CharType> REGEX_NODE_PUNCT = String("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
-
- switch (type) {
- case Type_alnum:
- if ('0' <= c && c <= '9') return true;
- if ('a' <= c && c <= 'z') return true;
- if ('A' <= c && c <= 'Z') return true;
- return false;
- case Type_alpha:
- if ('a' <= c && c <= 'z') return true;
- if ('A' <= c && c <= 'Z') return true;
- return false;
- case Type_ascii:
- return (0x00 <= c && c <= 0x7F);
- case Type_blank:
- return (c == ' ' || c == '\t');
- case Type_cntrl:
- return ((0x00 <= c && c <= 0x1F) || c == 0x7F);
- case Type_digit:
- return ('0' <= c && c <= '9');
- case Type_graph:
- return (0x20 < c && c < 0x7F);
- case Type_lower:
- return ('a' <= c && c <= 'z');
- case Type_print:
- return (0x20 < c && c < 0x7f);
- case Type_punct:
- return (REGEX_NODE_PUNCT.find(c) >= 0);
- case Type_space:
- return (REGEX_NODE_SPACE.find(c) >= 0);
- case Type_upper:
- return ('A' <= c && c <= 'Z');
- case Type_xdigit:
- if ('0' <= c && c <= '9') return true;
- if ('a' <= c && c <= 'f') return true;
- if ('A' <= c && c <= 'F') return true;
- return false;
- case Type_word:
- if ('0' <= c && c <= '9') return true;
- if ('a' <= c && c <= 'z') return true;
- if ('A' <= c && c <= 'Z') return true;
- return (c == '_');
- default:
- return false;
+ if (start == -1) {
+ result.append(String());
+ continue;
}
- return false;
- }
-
- RegExNodeClass(Type p_type) {
-
- length = 1;
- quantifiable = true;
- type = p_type;
- }
-
- virtual int test(RegExSearch &s, int pos) const {
-
- if (s.end <= pos || 0 > pos)
- return -1;
-
- if (!test_class(s.at(pos)))
- return -1;
-
- return next ? next->test(s, pos + 1) : pos + 1;
- }
-
-#define REGEX_CMP_CLASS(POS, NAME) \
- if (cmp_class(POS, #NAME)) return Type_##NAME
-
- static Type parse_type(const CharType *&p_pos) {
-
- REGEX_CMP_CLASS(p_pos, alnum);
- REGEX_CMP_CLASS(p_pos, alpha);
- REGEX_CMP_CLASS(p_pos, ascii);
- REGEX_CMP_CLASS(p_pos, blank);
- REGEX_CMP_CLASS(p_pos, cntrl);
- REGEX_CMP_CLASS(p_pos, digit);
- REGEX_CMP_CLASS(p_pos, graph);
- REGEX_CMP_CLASS(p_pos, lower);
- REGEX_CMP_CLASS(p_pos, print);
- REGEX_CMP_CLASS(p_pos, punct);
- REGEX_CMP_CLASS(p_pos, space);
- REGEX_CMP_CLASS(p_pos, upper);
- REGEX_CMP_CLASS(p_pos, xdigit);
- REGEX_CMP_CLASS(p_pos, word);
- return Type_none;
- }
-
- static bool cmp_class(const CharType *&p_pos, const char *p_text) {
-
- unsigned int i = 0;
- for (i = 0; p_text[i] != '\0'; ++i)
- if (p_pos[i] != p_text[i])
- return false;
-
- if (p_pos[i++] != ':' || p_pos[i] != ']')
- return false;
-
- p_pos = &p_pos[i];
- return true;
- }
-};
-
-struct RegExNodeAnchorStart : public RegExNode {
- RegExNodeAnchorStart() {
+ int length = data[i].end - start;
- length = 0;
+ result.append(subject.substr(start, length));
}
- virtual int test(RegExSearch &s, int pos) const {
+ return result;
+}
- if (pos != 0)
- return -1;
+String RegExMatch::get_string(const Variant &p_name) const {
- return next ? next->test(s, pos) : pos;
- }
-};
+ int id = _find(p_name);
-struct RegExNodeAnchorEnd : public RegExNode {
+ if (id < 0)
+ return String();
- RegExNodeAnchorEnd() {
+ int start = data[id].start;
- length = 0;
- }
+ if (start == -1)
+ return String();
- virtual int test(RegExSearch &s, int pos) const {
+ int length = data[id].end - start;
- if (pos != s.eof)
- return -1;
+ return subject.substr(start, length);
+}
- return next ? next->test(s, pos) : pos;
- }
-};
+int RegExMatch::get_start(const Variant &p_name) const {
-struct RegExNodeWordBoundary : public RegExNode {
+ int id = _find(p_name);
- bool inverse;
+ if (id < 0)
+ return -1;
- RegExNodeWordBoundary(bool p_inverse) {
+ return data[id].start;
+}
- length = 0;
- inverse = p_inverse;
- }
+int RegExMatch::get_end(const Variant &p_name) const {
- virtual int test(RegExSearch &s, int pos) const {
+ int id = _find(p_name);
- bool left = false;
- bool right = false;
+ if (id < 0)
+ return -1;
- if (pos != 0) {
- CharType c = s.at(pos - 1);
- if (c == '_' || iswalnum(c))
- left = true;
- }
+ return data[id].end;
+}
- if (pos != s.eof) {
- CharType c = s.at(pos);
- if (c == '_' || iswalnum(c))
- right = true;
- }
+void RegExMatch::_bind_methods() {
- if ((left == right) != inverse)
- return -1;
+ ClassDB::bind_method(D_METHOD("get_subject"), &RegExMatch::get_subject);
+ ClassDB::bind_method(D_METHOD("get_group_count"), &RegExMatch::get_group_count);
+ ClassDB::bind_method(D_METHOD("get_names"), &RegExMatch::get_names);
+ ClassDB::bind_method(D_METHOD("get_strings"), &RegExMatch::get_strings);
+ ClassDB::bind_method(D_METHOD("get_string", "name"), &RegExMatch::get_string, DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("get_start", "name"), &RegExMatch::get_start, DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("get_end", "name"), &RegExMatch::get_end, DEFVAL(0));
+}
- return next ? next->test(s, pos) : pos;
- }
-};
+void RegEx::_pattern_info(uint32_t what, void *where) const {
-struct RegExNodeQuantifier : public RegExNode {
+ if (sizeof(CharType) == 2) {
- int min;
- int max;
- bool greedy;
- RegExNode *child;
+ pcre2_pattern_info_16((pcre2_code_16 *)code, what, where);
- RegExNodeQuantifier(int p_min, int p_max) {
+ } else {
- min = p_min;
- max = p_max;
- greedy = true;
- child = NULL;
+ pcre2_pattern_info_32((pcre2_code_32 *)code, what, where);
}
+}
- ~RegExNodeQuantifier() {
-
- if (child)
- memdelete(child);
- }
+void RegEx::clear() {
- virtual int test(RegExSearch &s, int pos) const {
+ if (sizeof(CharType) == 2) {
- return test_step(s, pos, 0, pos);
- }
+ if (code)
+ pcre2_code_free_16((pcre2_code_16 *)code);
- virtual int test_parent(RegExSearch &s, int pos) const {
+ } else {
- s.complete = false;
- return pos;
+ if (code)
+ pcre2_code_free_32((pcre2_code_32 *)code);
}
+}
- int test_step(RegExSearch &s, int pos, int level, int start) const {
-
- if (pos > s.end)
- return -1;
-
- if (!greedy && level > min) {
- int res = next ? next->test(s, pos) : pos;
- if (s.complete)
- return res;
-
- if (res >= 0 && parent->test_parent(s, res) >= 0)
- return res;
- }
-
- if (max >= 0 && level > max)
- return -1;
+Error RegEx::compile(const String &p_pattern) {
- int res = pos;
- if (level >= 1) {
- if (level > min + 1 && pos == start)
- return -1;
+ pattern = p_pattern;
+ clear();
- res = child->test(s, pos);
- if (s.complete)
- return res;
- }
+ int err;
+ PCRE2_SIZE offset;
+ uint32_t flags = PCRE2_DUPNAMES;
- if (res >= 0) {
+ if (sizeof(CharType) == 2) {
- int res_step = test_step(s, res, level + 1, start);
- if (res_step >= 0)
- return res_step;
+ pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
+ pcre2_compile_context_16 *cctx = pcre2_compile_context_create_16(gctx);
+ PCRE2_SPTR16 p = (PCRE2_SPTR16)pattern.c_str();
- if (greedy && level >= min) {
- if (next)
- res = next->test(s, res);
- if (s.complete)
- return res;
+ code = pcre2_compile_16(p, pattern.length(), flags, &err, &offset, cctx);
- if (res >= 0 && parent->test_parent(s, res) >= 0)
- return res;
- }
+ if (!code) {
+ PCRE2_UCHAR16 buf[256];
+ pcre2_get_error_message_16(err, buf, 256);
+ String message = String::num(offset) + ": " + String((const CharType *)buf);
+ ERR_PRINT(message.utf8());
+ return FAILED;
}
- return -1;
- }
-};
-
-struct RegExNodeBackReference : public RegExNode {
- int id;
+ } else {
- RegExNodeBackReference(int p_id) {
-
- length = -1;
- quantifiable = true;
- id = p_id;
- }
+ pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
+ pcre2_compile_context_32 *cctx = pcre2_compile_context_create_32(gctx);
+ PCRE2_SPTR32 p = (PCRE2_SPTR32)pattern.c_str();
- virtual int test(RegExSearch &s, int pos) const {
+ code = pcre2_compile_32(p, pattern.length(), flags, &err, &offset, cctx);
- RegExMatch::Group &ref = s.match->captures[id];
- for (int i = 0; i < ref.length; ++i) {
-
- if (pos + i >= s.end)
- return -1;
-
- if (s.at(ref.start + i) != s.at(pos + i))
- return -1;
+ if (!code) {
+ PCRE2_UCHAR32 buf[256];
+ pcre2_get_error_message_32(err, buf, 256);
+ String message = String::num(offset) + ": " + String((const CharType *)buf);
+ ERR_PRINT(message.utf8());
+ return FAILED;
}
- return next ? next->test(s, pos + ref.length) : pos + ref.length;
}
-};
-
-struct RegExNodeGroup : public RegExNode {
-
- bool inverse;
- bool reset_pos;
- Vector<RegExNode *> childset;
- RegExNode *back;
-
- RegExNodeGroup() {
-
- length = 0;
- quantifiable = true;
- inverse = false;
- reset_pos = false;
- back = NULL;
- }
-
- virtual ~RegExNodeGroup() {
-
- for (int i = 0; i < childset.size(); ++i)
- memdelete(childset[i]);
- }
-
- virtual void test_success(RegExSearch &s, int pos) const {
+ return OK;
+}
- return;
- }
+Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) const {
- virtual int test(RegExSearch &s, int pos) const {
+ ERR_FAIL_COND_V(!is_valid(), NULL);
- for (int i = 0; i < childset.size(); ++i) {
+ Ref<RegExMatch> result = memnew(RegExMatch);
- s.complete = false;
+ int length = p_subject.length();
+ if (p_end >= 0 && p_end < length)
+ length = p_end;
- int res = childset[i]->test(s, pos);
+ if (sizeof(CharType) == 2) {
- if (inverse) {
- s.complete = false;
- if (res < 0)
- res = pos + 1;
- else
- return -1;
+ pcre2_code_16 *c = (pcre2_code_16 *)code;
+ pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
+ pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx);
+ PCRE2_SPTR16 s = (PCRE2_SPTR16)p_subject.c_str();
- if (i + 1 < childset.size())
- continue;
- }
+ pcre2_match_data_16 *match = pcre2_match_data_create_from_pattern_16(c, gctx);
- if (s.complete)
- return res;
+ int res = pcre2_match_16(c, s, length, p_offset, 0, match, mctx);
- if (res >= 0) {
- if (reset_pos)
- res = pos;
- this->test_success(s, res);
- return next ? next->test(s, res) : res;
- }
+ if (res < 0) {
+ pcre2_match_data_free_16(match);
+ return NULL;
}
- return -1;
- }
-
- void add_child(RegExNode *node) {
- node->parent = this;
- node->previous = back;
+ uint32_t size = pcre2_get_ovector_count_16(match);
+ PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_16(match);
- if (back)
- back->next = node;
- else
- childset.push_back(node);
+ result->data.resize(size);
- increment_length(node->length);
+ for (uint32_t i = 0; i < size; i++) {
- back = node;
- }
-
- void add_childset() {
-
- if (childset.size() > 0)
- length = -1;
- back = NULL;
- }
-
- RegExNode *swap_back(RegExNode *node) {
-
- RegExNode *old = back;
-
- if (old) {
- if (!old->previous)
- childset.remove(childset.size() - 1);
- back = old->previous;
- increment_length(old->length, true);
+ result->data[i].start = ovector[i * 2];
+ result->data[i].end = ovector[i * 2 + 1];
}
- add_child(node);
+ pcre2_match_data_free_16(match);
+ pcre2_match_context_free_16(mctx);
- return old;
- }
-};
+ } else {
-struct RegExNodeCapturing : public RegExNodeGroup {
+ pcre2_code_32 *c = (pcre2_code_32 *)code;
+ pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
+ pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
+ PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.c_str();
- int id;
+ pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx);
- RegExNodeCapturing(int p_id = 0) {
+ int res = pcre2_match_32(c, s, length, p_offset, 0, match, mctx);
- id = p_id;
- }
-
- virtual void test_success(RegExSearch &s, int pos) const {
-
- RegExMatch::Group &ref = s.match->captures[id];
- ref.length = pos - ref.start;
- }
-
- virtual int test(RegExSearch &s, int pos) const {
-
- RegExMatch::Group &ref = s.match->captures[id];
- int old_start = ref.start;
- ref.start = pos;
-
- int res = RegExNodeGroup::test(s, pos);
-
- if (res < 0)
- ref.start = old_start;
- return res;
- }
-
- virtual int test_parent(RegExSearch &s, int pos) const {
-
- RegExMatch::Group &ref = s.match->captures[id];
- ref.length = pos - ref.start;
- return RegExNode::test_parent(s, pos);
- }
-
- static Variant parse_name(const CharType *&c, bool p_allow_numeric) {
-
- if (c[1] == '0') {
- return -1;
- } else if ('1' <= c[1] && c[1] <= '9') {
- if (!p_allow_numeric)
- return -1;
- int res = (++c)[0] - '0';
- while ('0' <= c[1] && c[1] <= '9')
- res = res * 10 + int((++c)[0] - '0');
- if ((++c)[0] != '>')
- return -1;
- return res;
- } else if (iswalnum(c[1])) {
- String res(++c, 1);
- while (iswalnum(c[1]))
- res += String(++c, 1);
- if ((++c)[0] != '>')
- return -1;
- return res;
+ if (res < 0) {
+ pcre2_match_data_free_32(match);
+ return NULL;
}
- return -1;
- }
-};
-
-struct RegExNodeLookAhead : public RegExNodeGroup {
-
- int id;
- RegExNodeLookAhead(bool p_inverse, int p_id = 0) {
+ uint32_t size = pcre2_get_ovector_count_32(match);
+ PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_32(match);
- quantifiable = false;
- inverse = p_inverse;
- reset_pos = true;
- id = p_id;
- }
-
- virtual int test(RegExSearch &s, int pos) const {
+ result->data.resize(size);
- s.lookahead_pos[id] = pos;
- return RegExNodeGroup::test(s, pos);
- }
+ for (uint32_t i = 0; i < size; i++) {
- virtual int test_parent(RegExSearch &s, int pos) const {
+ result->data[i].start = ovector[i * 2];
+ result->data[i].end = ovector[i * 2 + 1];
+ }
- return RegExNode::test_parent(s, s.lookahead_pos[id]);
+ pcre2_match_data_free_32(match);
+ pcre2_match_context_free_32(mctx);
}
-};
-struct RegExNodeLookBehind : public RegExNodeGroup {
+ result->subject = p_subject;
- RegExNodeLookBehind(bool p_inverse, int p_id = 0) {
+ uint32_t count;
+ const CharType *table;
+ uint32_t entry_size;
- quantifiable = false;
- inverse = p_inverse;
- reset_pos = true;
- }
+ _pattern_info(PCRE2_INFO_NAMECOUNT, &count);
+ _pattern_info(PCRE2_INFO_NAMETABLE, &table);
+ _pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size);
- virtual bool is_look_behind() { return true; }
+ for (uint32_t i = 0; i < count; i++) {
- virtual int test(RegExSearch &s, int pos) const {
+ CharType id = table[i * entry_size];
+ if (result->data[id].start == -1)
+ continue;
+ String name = &table[i * entry_size + 1];
+ if (result->names.has(name))
+ continue;
- if (pos < length)
- return -1;
- return RegExNodeGroup::test(s, pos - length);
+ result->names.insert(name, id);
}
-};
-struct RegExNodeBracket : public RegExNode {
+ return result;
+}
- bool inverse;
- Vector<RegExNode *> children;
+String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_all, int p_offset, int p_end) const {
- RegExNodeBracket() {
+ ERR_FAIL_COND_V(!is_valid(), String());
- length = 1;
- quantifiable = true;
- inverse = false;
- }
+ String output;
+ output.resize(p_subject.length());
- virtual ~RegExNodeBracket() {
+ uint32_t flags = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH;
+ if (p_all)
+ flags |= PCRE2_SUBSTITUTE_GLOBAL;
- for (int i = 0; i < children.size(); ++i)
- memdelete(children[i]);
- }
+ PCRE2_SIZE olength = output.length();
- virtual int test(RegExSearch &s, int pos) const {
+ PCRE2_SIZE length = p_subject.length();
+ if (p_end >= 0 && (uint32_t)p_end < length)
+ length = p_end;
- for (int i = 0; i < children.size(); ++i) {
+ if (sizeof(CharType) == 2) {
- int res = children[i]->test(s, pos);
+ pcre2_code_16 *c = (pcre2_code_16 *)code;
+ pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
+ pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx);
+ PCRE2_SPTR16 s = (PCRE2_SPTR16)p_subject.c_str();
+ PCRE2_SPTR16 r = (PCRE2_SPTR16)p_replacement.c_str();
+ PCRE2_UCHAR16 *o = (PCRE2_UCHAR16 *)output.c_str();
- if (inverse) {
- if (res < 0)
- res = pos + 1;
- else
- return -1;
+ pcre2_match_data_16 *match = pcre2_match_data_create_from_pattern_16(c, gctx);
- if (i + 1 < children.size())
- continue;
- }
+ int res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
- if (res >= 0)
- return next ? next->test(s, res) : res;
+ if (res == PCRE2_ERROR_NOMEMORY) {
+ output.resize(olength);
+ o = (PCRE2_UCHAR16 *)output.c_str();
+ res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
}
- return -1;
- }
- void add_child(RegExNode *node) {
-
- node->parent = this;
- children.push_back(node);
- }
+ pcre2_match_data_free_16(match);
+ pcre2_match_context_free_16(mctx);
- void pop_back() {
-
- memdelete(children[children.size() - 1]);
- children.remove(children.size() - 1);
- }
-};
-
-#define REGEX_EXPAND_FAIL(MSG) \
- { \
- ERR_PRINT(MSG); \
- return String(); \
- }
-
-String RegExMatch::expand(const String &p_template) const {
-
- String res;
- for (const CharType *c = p_template.c_str(); *c != '\0'; ++c) {
- if (c[0] == '\\') {
- if (('1' <= c[1] && c[1] <= '9') || (c[1] == 'g' && c[2] == '{')) {
-
- int ref = 0;
- bool unclosed = false;
-
- if (c[1] == 'g') {
- unclosed = true;
- c = &c[2];
- }
-
- while ('0' <= c[1] && c[1] <= '9') {
- ref = ref * 10 + int(c[1] - '0');
- ++c;
- }
-
- if (unclosed) {
- if (c[1] != '}')
- REGEX_EXPAND_FAIL("unclosed backreference '{'");
- ++c;
- }
-
- res += get_string(ref);
-
- } else if (c[1] == 'g' && c[2] == '<') {
-
- const CharType *d = &c[2];
+ if (res < 0)
+ return String();
- Variant name = RegExNodeCapturing::parse_name(d, true);
- if (name == Variant(-1))
- REGEX_EXPAND_FAIL("unrecognised character for group name");
+ } else {
- c = d;
+ pcre2_code_32 *c = (pcre2_code_32 *)code;
+ pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
+ pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
+ PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.c_str();
+ PCRE2_SPTR32 r = (PCRE2_SPTR32)p_replacement.c_str();
+ PCRE2_UCHAR32 *o = (PCRE2_UCHAR32 *)output.c_str();
- res += get_string(name);
+ pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx);
- } else {
+ int res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
- const CharType *d = c;
- CharType ch = RegExNodeChar::parse_escape(d);
- if (c == d)
- REGEX_EXPAND_FAIL("invalid escape token");
- res += String(&ch, 1);
- c = d;
- }
- } else {
- res += String(c, 1);
+ if (res == PCRE2_ERROR_NOMEMORY) {
+ output.resize(olength);
+ o = (PCRE2_UCHAR32 *)output.c_str();
+ res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
}
- }
- return res;
-}
-int RegExMatch::get_group_count() const {
+ pcre2_match_data_free_32(match);
+ pcre2_match_context_free_32(mctx);
- int count = 0;
- for (int i = 1; i < captures.size(); ++i)
- if (captures[i].name.get_type() == Variant::INT)
- ++count;
- return count;
-}
-
-Array RegExMatch::get_group_array() const {
-
- Array res;
- for (int i = 1; i < captures.size(); ++i) {
- const RegExMatch::Group &capture = captures[i];
- if (capture.name.get_type() != Variant::INT)
- continue;
-
- if (capture.start >= 0)
- res.push_back(string.substr(capture.start, capture.length));
- else
- res.push_back(String());
- }
- return res;
-}
-
-Array RegExMatch::get_names() const {
-
- Array res;
- for (int i = 1; i < captures.size(); ++i)
- if (captures[i].name.get_type() == Variant::STRING)
- res.push_back(captures[i].name);
- return res;
-}
-
-Dictionary RegExMatch::get_name_dict() const {
-
- Dictionary res;
- for (int i = 1; i < captures.size(); ++i) {
- const RegExMatch::Group &capture = captures[i];
- if (capture.name.get_type() != Variant::STRING)
- continue;
-
- if (capture.start >= 0)
- res[capture.name] = string.substr(capture.start, capture.length);
- else
- res[capture.name] = String();
- }
- return res;
-}
-
-String RegExMatch::get_string(const Variant &p_name) const {
-
- for (int i = 0; i < captures.size(); ++i) {
-
- const RegExMatch::Group &capture = captures[i];
-
- if (capture.name != p_name)
- continue;
-
- if (capture.start == -1)
+ if (res < 0)
return String();
-
- return string.substr(capture.start, capture.length);
}
- return String();
-}
-
-int RegExMatch::get_start(const Variant &p_name) const {
- for (int i = 0; i < captures.size(); ++i)
- if (captures[i].name == p_name)
- return captures[i].start;
- return -1;
+ return output;
}
-int RegExMatch::get_end(const Variant &p_name) const {
+bool RegEx::is_valid() const {
- for (int i = 0; i < captures.size(); ++i)
- if (captures[i].name == p_name)
- return captures[i].start + captures[i].length;
- return -1;
+ return (code != NULL);
}
-RegExMatch::RegExMatch() {
-}
+String RegEx::get_pattern() const {
-static bool RegEx_is_shorthand(CharType ch) {
-
- switch (ch) {
- case 'w':
- case 'W':
- case 'd':
- case 'D':
- case 's':
- case 'S':
- return true;
- default:
- break;
- }
- return false;
+ return pattern;
}
-#define REGEX_COMPILE_FAIL(MSG) \
- { \
- ERR_PRINT(MSG); \
- clear(); \
- return FAILED; \
- }
+int RegEx::get_group_count() const {
-Error RegEx::compile(const String &p_pattern) {
+ ERR_FAIL_COND_V(!is_valid(), 0);
- ERR_FAIL_COND_V(p_pattern.length() == 0, FAILED);
+ uint32_t count;
- if (pattern == p_pattern && root)
- return OK;
+ _pattern_info(PCRE2_INFO_CAPTURECOUNT, &count);
- clear();
- pattern = p_pattern;
- group_names.push_back(0);
- RegExNodeGroup *root_group = memnew(RegExNodeCapturing(0));
- root = root_group;
- Vector<RegExNodeGroup *> stack;
- stack.push_back(root_group);
- int lookahead_level = 0;
- int numeric_groups = 0;
- const int numeric_max = 9;
-
- for (const CharType *c = p_pattern.c_str(); *c != '\0'; ++c) {
-
- switch (c[0]) {
- case '(':
- if (c[1] == '?') {
-
- RegExNodeGroup *group = NULL;
- switch (c[2]) {
- case ':':
- c = &c[2];
- group = memnew(RegExNodeGroup());
- break;
- case '!':
- case '=':
- group = memnew(RegExNodeLookAhead((c[2] == '!'), lookahead_level++));
- if (lookahead_depth < lookahead_level)
- lookahead_depth = lookahead_level;
- c = &c[2];
- break;
- case '<':
- if (c[3] == '!' || c[3] == '=') {
- group = memnew(RegExNodeLookBehind((c[3] == '!'), lookahead_level++));
- c = &c[3];
- }
- break;
- case 'P':
- if (c[3] == '<') {
- const CharType *d = &c[3];
- Variant name = RegExNodeCapturing::parse_name(d, false);
- if (name == Variant(-1))
- REGEX_COMPILE_FAIL("unrecognised character for group name");
- group = memnew(RegExNodeCapturing(group_names.size()));
- group_names.push_back(name);
- c = d;
- }
- default:
- break;
- }
- if (!group)
- REGEX_COMPILE_FAIL("unrecognised qualifier for group");
- stack[0]->add_child(group);
- stack.insert(0, group);
-
- } else if (numeric_groups < numeric_max) {
-
- RegExNodeCapturing *group = memnew(RegExNodeCapturing(group_names.size()));
- group_names.push_back(++numeric_groups);
- stack[0]->add_child(group);
- stack.insert(0, group);
-
- } else {
-
- RegExNodeGroup *group = memnew(RegExNodeGroup());
- stack[0]->add_child(group);
- stack.insert(0, group);
- }
- break;
- case ')':
- if (stack.size() == 1)
- REGEX_COMPILE_FAIL("unexpected ')'");
- stack.remove(0);
- break;
- case '\\':
- if (('1' <= c[1] && c[1] <= '9') || (c[1] == 'g' && c[2] == '{')) {
-
- int ref = 0;
- bool unclosed = false;
-
- if (c[1] == 'g') {
- unclosed = true;
- c = &c[2];
- }
-
- while ('0' <= c[1] && c[1] <= '9') {
- ref = ref * 10 + int(c[1] - '0');
- ++c;
- }
-
- if (unclosed) {
- if (c[1] != '}')
- REGEX_COMPILE_FAIL("unclosed backreference '{'");
- ++c;
- }
-
- if (ref > numeric_groups || ref <= 0)
- REGEX_COMPILE_FAIL("backreference not found");
-
- for (int i = 0; i < stack.size(); ++i)
- if (stack[i]->is_look_behind())
- REGEX_COMPILE_FAIL("backreferences inside lookbehind not supported");
-
- for (int i = 0; i < group_names.size(); ++i) {
- if (group_names[i].get_type() == Variant::INT && int(group_names[i]) == ref) {
- ref = group_names[i];
- break;
- }
- }
-
- stack[0]->add_child(memnew(RegExNodeBackReference(ref)));
- }
- if (c[1] == 'g' && c[2] == '<') {
-
- const CharType *d = &c[2];
-
- Variant name = RegExNodeCapturing::parse_name(d, true);
- if (name == Variant(-1))
- REGEX_COMPILE_FAIL("unrecognised character for group name");
-
- c = d;
-
- for (int i = 0; i < stack.size(); ++i)
- if (stack[i]->is_look_behind())
- REGEX_COMPILE_FAIL("backreferences inside lookbehind not supported");
-
- int ref = -1;
-
- for (int i = 0; i < group_names.size(); ++i) {
- if (group_names[i].get_type() == Variant::INT && int(group_names[i]) == ref) {
- ref = group_names[i];
- break;
- }
- }
-
- if (ref == -1)
- REGEX_COMPILE_FAIL("backreference not found");
-
- stack[0]->add_child(memnew(RegExNodeBackReference(ref)));
-
- } else if (c[1] == 'b' || c[1] == 'B') {
-
- stack[0]->add_child(memnew(RegExNodeWordBoundary(*(++c) == 'B')));
-
- } else if (RegEx_is_shorthand(c[1])) {
-
- stack[0]->add_child(memnew(RegExNodeShorthand(*(++c))));
-
- } else {
-
- const CharType *d = c;
- CharType ch = RegExNodeChar::parse_escape(d);
- if (c == d)
- REGEX_COMPILE_FAIL("invalid escape token");
- stack[0]->add_child(memnew(RegExNodeChar(ch)));
- c = d;
- }
- break;
- case '[': {
- RegExNodeBracket *bracket = memnew(RegExNodeBracket());
- stack[0]->add_child(bracket);
- if (c[1] == '^') {
- bracket->inverse = true;
- ++c;
- }
- bool first_child = true;
- CharType previous_child;
- bool previous_child_single = false;
- while (true) {
- ++c;
- if (!first_child && c[0] == ']') {
-
- break;
-
- } else if (c[0] == '\0') {
-
- REGEX_COMPILE_FAIL("unclosed bracket expression '['");
-
- } else if (c[0] == '\\') {
-
- if (RegEx_is_shorthand(c[1])) {
- bracket->add_child(memnew(RegExNodeShorthand(*(++c))));
- } else {
- const CharType *d = c;
- CharType ch = RegExNodeChar::parse_escape(d);
- if (c == d)
- REGEX_COMPILE_FAIL("invalid escape token");
- bracket->add_child(memnew(RegExNodeChar(ch)));
- c = d;
- previous_child = ch;
- previous_child_single = true;
- }
-
- } else if (c[0] == ']' && c[1] == ':') {
-
- const CharType *d = &c[2];
- RegExNodeClass::Type type = RegExNodeClass::parse_type(d);
- if (type != RegExNodeClass::Type_none) {
-
- c = d;
- previous_child_single = false;
-
- } else {
-
- bracket->add_child(memnew(RegExNodeChar('[')));
- previous_child = '[';
- previous_child_single = true;
- }
- } else if (previous_child_single && c[0] == '-') {
-
- if (c[1] != '\0' && c[1] != ']') {
-
- CharType next;
-
- if (c[1] == '\\') {
- const CharType *d = ++c;
- next = RegExNodeChar::parse_escape(d);
- if (c == d)
- REGEX_COMPILE_FAIL("invalid escape token");
- } else {
- next = *(++c);
- }
-
- if (next < previous_child)
- REGEX_COMPILE_FAIL("text range out of order");
-
- bracket->pop_back();
- bracket->add_child(memnew(RegExNodeRange(previous_child, next)));
- previous_child_single = false;
- } else {
-
- bracket->add_child(memnew(RegExNodeChar('-')));
- previous_child = '-';
- previous_child_single = true;
- }
- } else {
-
- bracket->add_child(memnew(RegExNodeChar(c[0])));
- previous_child = c[0];
- previous_child_single = true;
- }
- first_child = false;
- }
- } break;
- case '|':
- for (int i = 0; i < stack.size(); ++i)
- if (stack[i]->is_look_behind())
- REGEX_COMPILE_FAIL("alternations inside lookbehind not supported");
- stack[0]->add_childset();
- break;
- case '^':
- stack[0]->add_child(memnew(RegExNodeAnchorStart()));
- break;
- case '$':
- stack[0]->add_child(memnew(RegExNodeAnchorEnd()));
- break;
- case '.':
- stack[0]->add_child(memnew(RegExNodeShorthand('.')));
- break;
- case '?':
- case '*':
- case '+':
- case '{': {
- int min_val = 0;
- int max_val = -1;
- bool valid = true;
- const CharType *d = c;
- bool max_set = true;
- switch (c[0]) {
- case '?':
- min_val = 0;
- max_val = 1;
- break;
- case '*':
- min_val = 0;
- max_val = -1;
- break;
- case '+':
- min_val = 1;
- max_val = -1;
- break;
- case '{':
- max_set = false;
- while (valid) {
- ++d;
- if (d[0] == '}') {
- break;
- } else if (d[0] == ',') {
- max_set = true;
- } else if ('0' <= d[0] && d[0] <= '9') {
- if (max_set) {
- if (max_val < 0)
- max_val = int(d[0] - '0');
- else
- max_val = max_val * 10 + int(d[0] - '0');
- } else {
- min_val = min_val * 10 + int(d[0] - '0');
- }
- } else {
- valid = false;
- }
- }
- break;
- default:
- break;
- }
-
- if (!max_set)
- max_val = min_val;
-
- if (valid) {
-
- c = d;
-
- if (stack[0]->back == NULL || !stack[0]->back->quantifiable)
- REGEX_COMPILE_FAIL("element not quantifiable");
-
- if (min_val != max_val)
- for (int i = 0; i < stack.size(); ++i)
- if (stack[i]->is_look_behind())
- REGEX_COMPILE_FAIL("variable length quantifiers inside lookbehind not supported");
-
- RegExNodeQuantifier *quant = memnew(RegExNodeQuantifier(min_val, max_val));
- quant->child = stack[0]->swap_back(quant);
- quant->child->previous = NULL;
- quant->child->parent = quant;
-
- if (min_val == max_val && quant->child->length >= 0)
- quant->length = max_val * quant->child->length;
-
- if (c[1] == '?') {
- quant->greedy = false;
- ++c;
- }
- break;
- }
- }
- default:
- stack[0]->add_child(memnew(RegExNodeChar(c[0])));
- break;
- }
- }
- if (stack.size() > 1)
- REGEX_COMPILE_FAIL("unclosed group '('");
- return OK;
+ return count;
}
-Ref<RegExMatch> RegEx::search(const String &p_text, int p_start, int p_end) const {
-
- ERR_FAIL_COND_V(!is_valid(), NULL);
- ERR_FAIL_COND_V(p_start < 0, NULL);
- ERR_FAIL_COND_V(p_start >= p_text.length(), NULL);
- ERR_FAIL_COND_V(p_end > p_text.length(), NULL);
- ERR_FAIL_COND_V(p_end != -1 && p_end < p_start, NULL);
+Array RegEx::get_names() const {
- Ref<RegExMatch> res = memnew(RegExMatch());
+ Array result;
- for (int i = 0; i < group_names.size(); ++i) {
- RegExMatch::Group group;
- group.name = group_names[i];
- res->captures.push_back(group);
- }
+ ERR_FAIL_COND_V(!is_valid(), result);
- res->string = p_text;
+ uint32_t count;
+ const CharType *table;
+ uint32_t entry_size;
- if (p_end == -1)
- p_end = p_text.length();
+ _pattern_info(PCRE2_INFO_NAMECOUNT, &count);
+ _pattern_info(PCRE2_INFO_NAMETABLE, &table);
+ _pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size);
- RegExSearch s(res, p_end, lookahead_depth);
+ for (uint32_t i = 0; i < count; i++) {
- for (int i = p_start; i <= s.end; ++i) {
- for (int c = 0; c < group_names.size(); ++c) {
- res->captures[c].start = -1;
- res->captures[c].length = 0;
+ String name = &table[i * entry_size + 1];
+ if (result.find(name) < 0) {
+ result.append(name);
}
- if (root->test(s, i) >= 0)
- break;
}
- if (res->captures[0].start >= 0)
- return res;
- return NULL;
+ return result;
}
-String RegEx::sub(const String &p_text, const String &p_replacement, bool p_all, int p_start, int p_end) const {
-
- ERR_FAIL_COND_V(!is_valid(), p_text);
- ERR_FAIL_COND_V(p_start < 0, p_text);
- ERR_FAIL_COND_V(p_start >= p_text.length(), p_text);
- ERR_FAIL_COND_V(p_end > p_text.length(), p_text);
- ERR_FAIL_COND_V(p_end != -1 && p_end < p_start, p_text);
-
- String text = p_text;
- int start = p_start;
-
- if (p_end == -1)
- p_end = p_text.length();
-
- while (start < text.length() && (p_all || start == p_start)) {
-
- Ref<RegExMatch> m = search(text, start, p_end);
-
- RegExMatch::Group &s = m->captures[0];
-
- if (s.start < 0)
- break;
-
- String res = text.substr(0, s.start) + m->expand(p_replacement);
-
- start = res.length();
+RegEx::RegEx() {
- if (s.length == 0)
- ++start;
+ if (sizeof(CharType) == 2) {
- int sub_end = s.start + s.length;
- if (sub_end < text.length())
- res += text.substr(sub_end, text.length() - sub_end);
+ general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, NULL);
- p_end += res.length() - text.length();
+ } else {
- text = res;
+ general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, NULL);
}
- return text;
+ code = NULL;
}
-void RegEx::clear() {
-
- if (root)
- memdelete(root);
-
- root = NULL;
- group_names.clear();
- lookahead_depth = 0;
-}
-
-bool RegEx::is_valid() const {
-
- return (root != NULL);
-}
-
-String RegEx::get_pattern() const {
-
- return pattern;
-}
-
-int RegEx::get_group_count() const {
-
- int count = 0;
- for (int i = 1; i < group_names.size(); ++i)
- if (group_names[i].get_type() == Variant::INT)
- ++count;
- return count;
-}
-
-Array RegEx::get_names() const {
+RegEx::RegEx(const String &p_pattern) {
- Array res;
- for (int i = 1; i < group_names.size(); ++i)
- if (group_names[i].get_type() == Variant::STRING)
- res.push_back(group_names[i]);
- return res;
-}
+ if (sizeof(CharType) == 2) {
-RegEx::RegEx() {
+ general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, NULL);
- root = NULL;
- lookahead_depth = 0;
-}
+ } else {
-RegEx::RegEx(const String &p_pattern) {
-
- root = NULL;
+ general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, NULL);
+ }
+ code = NULL;
compile(p_pattern);
}
RegEx::~RegEx() {
- if (root)
- memdelete(root);
-}
+ if (sizeof(CharType) == 2) {
-void RegExMatch::_bind_methods() {
+ if (code)
+ pcre2_code_free_16((pcre2_code_16 *)code);
+ pcre2_general_context_free_16((pcre2_general_context_16 *)general_ctx);
- ClassDB::bind_method(D_METHOD("expand", "template"), &RegExMatch::expand);
- ClassDB::bind_method(D_METHOD("get_group_count"), &RegExMatch::get_group_count);
- ClassDB::bind_method(D_METHOD("get_group_array"), &RegExMatch::get_group_array);
- ClassDB::bind_method(D_METHOD("get_names"), &RegExMatch::get_names);
- ClassDB::bind_method(D_METHOD("get_name_dict"), &RegExMatch::get_name_dict);
- ClassDB::bind_method(D_METHOD("get_string", "name"), &RegExMatch::get_string, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("get_start", "name"), &RegExMatch::get_start, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("get_end", "name"), &RegExMatch::get_end, DEFVAL(0));
+ } else {
+
+ if (code)
+ pcre2_code_free_32((pcre2_code_32 *)code);
+ pcre2_general_context_free_32((pcre2_general_context_32 *)general_ctx);
+ }
}
void RegEx::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &RegEx::clear);
ClassDB::bind_method(D_METHOD("compile", "pattern"), &RegEx::compile);
- ClassDB::bind_method(D_METHOD("search", "text", "start", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("sub", "text", "replacement", "all", "start", "end"), &RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("search", "subject", "offset", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("sub", "subject", "replacement", "all", "offset", "end"), &RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("is_valid"), &RegEx::is_valid);
ClassDB::bind_method(D_METHOD("get_pattern"), &RegEx::get_pattern);
ClassDB::bind_method(D_METHOD("get_group_count"), &RegEx::get_group_count);
ClassDB::bind_method(D_METHOD("get_names"), &RegEx::get_names);
-
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "pattern"), "compile", "get_pattern");
}
diff --git a/modules/regex/regex.h b/modules/regex/regex.h
index 8c76035b82..0d97bcce54 100644
--- a/modules/regex/regex.h
+++ b/modules/regex/regex.h
@@ -31,59 +31,53 @@
#ifndef REGEX_H
#define REGEX_H
+#include "core/array.h"
#include "core/dictionary.h"
+#include "core/map.h"
#include "core/reference.h"
-#include "core/resource.h"
#include "core/ustring.h"
#include "core/vector.h"
-class RegExNode;
-
class RegExMatch : public Reference {
GDCLASS(RegExMatch, Reference);
- struct Group {
- Variant name;
+ struct Range {
int start;
- int length;
+ int end;
};
- Vector<Group> captures;
- String string;
+ String subject;
+ Vector<Range> data;
+ Map<String, int> names;
friend class RegEx;
- friend class RegExSearch;
- friend class RegExNodeCapturing;
- friend class RegExNodeBackReference;
protected:
static void _bind_methods();
-public:
- String expand(const String &p_template) const;
+ int _find(const Variant &p_name) const;
+public:
+ String get_subject() const;
int get_group_count() const;
- Array get_group_array() const;
-
- Array get_names() const;
- Dictionary get_name_dict() const;
+ Dictionary get_names() const;
+ Array get_strings() const;
String get_string(const Variant &p_name) const;
int get_start(const Variant &p_name) const;
int get_end(const Variant &p_name) const;
-
- RegExMatch();
};
-class RegEx : public Resource {
+class RegEx : public Reference {
- GDCLASS(RegEx, Resource);
+ GDCLASS(RegEx, Reference);
- RegExNode *root;
- Vector<Variant> group_names;
+ void *general_ctx;
+ void *code;
String pattern;
- int lookahead_depth;
+
+ void _pattern_info(uint32_t what, void *where) const;
protected:
static void _bind_methods();
@@ -91,9 +85,10 @@ protected:
public:
void clear();
Error compile(const String &p_pattern);
+ void _init(const String &p_pattern = "");
- Ref<RegExMatch> search(const String &p_text, int p_start = 0, int p_end = -1) const;
- String sub(const String &p_text, const String &p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const;
+ Ref<RegExMatch> search(const String &p_subject, int offset = 0, int end = -1) const;
+ String sub(const String &p_subject, const String &p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const;
bool is_valid() const;
String get_pattern() const;
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index 29073a8499..072f18b990 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -91,7 +91,7 @@ void image_compress_squish(Image *p_image, Image::CompressSource p_source) {
if (p_image->get_format() <= Image::FORMAT_RGBA8) {
int squish_comp = squish::kColourRangeFit;
- Image::Format target_format;
+ Image::Format target_format = Image::FORMAT_RGBA8;
Image::DetectChannels dc = p_image->get_detected_channels();
@@ -140,6 +140,10 @@ void image_compress_squish(Image *p_image, Image::CompressSource p_source) {
squish_comp |= squish::kDxt5;
} break;
+ default: {
+ ERR_PRINT("Unknown image format, defaulting to RGBA8");
+ break;
+ }
}
PoolVector<uint8_t> data;
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 49d959203c..df427907f8 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -31,7 +31,10 @@
#include "os/file_access.h"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#include "thirdparty/misc/stb_vorbis.c"
+#pragma GCC diagnostic pop
void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) {
@@ -112,8 +115,8 @@ float AudioStreamPlaybackOGGVorbis::get_length() const {
AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() {
if (ogg_alloc.alloc_buffer) {
- AudioServer::get_singleton()->audio_data_free(ogg_alloc.alloc_buffer);
stb_vorbis_close(ogg_stream);
+ AudioServer::get_singleton()->audio_data_free(ogg_alloc.alloc_buffer);
}
}
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
index a459e6f31d..bcd829a56a 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
@@ -34,7 +34,10 @@
#include "servers/audio/audio_stream.h"
#define STB_VORBIS_HEADER_ONLY
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#include "thirdparty/misc/stb_vorbis.c"
+#pragma GCC diagnostic pop
#undef STB_VORBIS_HEADER_ONLY
class AudioStreamOGGVorbis;
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 086cc202f9..f5c379d32e 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -47,7 +47,49 @@ SVGRasterizer::~SVGRasterizer() {
SVGRasterizer ImageLoaderSVG::rasterizer;
-Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample) {
+inline void change_nsvg_paint_color(NSVGpaint *p_paint, const uint32_t p_old, const uint32_t p_new) {
+
+ if (p_paint->type == NSVG_PAINT_COLOR) {
+ if (p_paint->color << 8 == p_old << 8) {
+ p_paint->color = p_new;
+ }
+ }
+
+ if (p_paint->type == NSVG_PAINT_LINEAR_GRADIENT || p_paint->type == NSVG_PAINT_RADIAL_GRADIENT) {
+ for (int stop_index = 0; stop_index < p_paint->gradient->nstops; stop_index++) {
+ if (p_paint->gradient->stops[stop_index].color << 8 == p_old << 8) {
+ p_paint->gradient->stops[stop_index].color = p_new;
+ }
+ }
+ }
+}
+void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image, const Dictionary p_colors) {
+ List<uint32_t> replace_colors_i;
+ List<uint32_t> new_colors_i;
+ List<Color> replace_colors;
+ List<Color> new_colors;
+
+ for (int i = 0; i < p_colors.keys().size(); i++) {
+ Variant r_c = p_colors.keys()[i];
+ Variant n_c = p_colors[p_colors.keys()[i]];
+ if (r_c.get_type() == Variant::COLOR && n_c.get_type() == Variant::COLOR) {
+ Color replace_color = r_c;
+ Color new_color = n_c;
+ replace_colors_i.push_back(replace_color.to_ABGR32());
+ new_colors_i.push_back(new_color.to_ABGR32());
+ }
+ }
+
+ for (NSVGshape *shape = p_svg_image->shapes; shape != NULL; shape = shape->next) {
+
+ for (int i = 0; i < replace_colors_i.size(); i++) {
+ change_nsvg_paint_color(&(shape->stroke), replace_colors_i[i], new_colors_i[i]);
+ change_nsvg_paint_color(&(shape->fill), replace_colors_i[i], new_colors_i[i]);
+ }
+ }
+}
+
+Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, const Dictionary *p_replace_colors) {
NSVGimage *svg_image;
PoolVector<uint8_t>::Read src_r = p_data->read();
svg_image = nsvgParse((char *)src_r.ptr(), "px", 96);
@@ -56,6 +98,9 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
return ERR_FILE_CORRUPT;
}
+ if (p_replace_colors != NULL) {
+ _convert_colors(svg_image, *p_replace_colors);
+ }
float upscale = upsample ? 2.0 : 1.0;
int w = (int)(svg_image->width * p_scale * upscale);
@@ -78,7 +123,7 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
return OK;
}
-Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *svg_str, float p_scale, bool upsample) {
+Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *svg_str, float p_scale, bool upsample, const Dictionary *p_replace_colors) {
size_t str_len = strlen(svg_str);
PoolVector<uint8_t> src_data;
@@ -86,7 +131,7 @@ Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *s
PoolVector<uint8_t>::Write src_w = src_data.write();
memcpy(src_w.ptr(), svg_str, str_len + 1);
- return _create_image(p_image, &src_data, p_scale, upsample);
+ return _create_image(p_image, &src_data, p_scale, upsample, p_replace_colors);
}
Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index 1f2ec3c1c2..f692b1b28c 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -54,14 +54,15 @@ public:
class ImageLoaderSVG : public ImageFormatLoader {
static SVGRasterizer rasterizer;
- static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample);
+ static void _convert_colors(NSVGimage *p_svg_imge, const Dictionary p_colors);
+ static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, const Dictionary *p_replace_color = NULL);
public:
- static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample);
+ static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, const Dictionary *p_replace_color = NULL);
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderSVG();
};
-#endif \ No newline at end of file
+#endif
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index 379c894550..7c7cf5bcbe 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* image_loader_jpegd.cpp */
+/* image_loader_tga.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -53,19 +53,19 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t
count = (c & 0x7f) + 1;
if (c & 0x80) {
- for (int i = 0; i < p_pixel_size; i++) {
+ for (size_t i = 0; i < p_pixel_size; i++) {
pixels_w.ptr()[i] = p_compressed_buffer[compressed_pos];
compressed_pos += 1;
}
- for (int i = 0; i < count; i++) {
- for (int j = 0; j < p_pixel_size; j++) {
+ for (size_t i = 0; i < count; i++) {
+ for (size_t j = 0; j < p_pixel_size; j++) {
p_uncompressed_buffer[output_pos + j] = pixels_w.ptr()[j];
}
output_pos += p_pixel_size;
}
} else {
count *= p_pixel_size;
- for (int i = 0; i < count; i++) {
+ for (size_t i = 0; i < count; i++) {
p_uncompressed_buffer[output_pos] = p_compressed_buffer[compressed_pos];
compressed_pos += 1;
output_pos += 1;
@@ -208,7 +208,7 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
PoolVector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
- ERR_FAIL_COND_V(src_image_len < sizeof(tga_header_s), ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(src_image_len < (int)sizeof(tga_header_s), ERR_FILE_CORRUPT);
src_image.resize(src_image_len);
Error err = OK;
diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h
index 8689a1773b..7905ab37a7 100644
--- a/modules/tga/image_loader_tga.h
+++ b/modules/tga/image_loader_tga.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* image_loader_jpegd.h */
+/* image_loader_tga.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 57826d69fb..49a4db237a 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* image_loader_jpegd.cpp */
+/* image_loader_tinyexr.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index adecba5d9d..53a81597af 100644
--- a/modules/tinyexr/image_loader_tinyexr.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* image_loader_jpegd.h */
+/* image_loader_tinyexr.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index b2e7a6aa27..297e9e510f 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -571,7 +571,6 @@ public:
virtual bool has_named_classes() const;
virtual int find_function(const String &p_function, const String &p_code) const;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
- virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; }
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 7ab2a93b55..37bd730d08 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* visual_script_editor.h */
+/* visual_script_editor.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -523,7 +523,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
if (Object::cast_to<VisualScriptExpression>(*node)) {
Ref<VisualScriptComment> vsc = node;
gnode->set_comment(true);
- gnode->set_resizeable(true);
+ gnode->set_resizable(true);
gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE);
gnode->connect("resize_request", this, "_comment_node_resized", varray(E->get()));
}
@@ -886,8 +886,8 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(this, "_update_members");
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
- undo_redo->add_do_method(this, "emit_signal", "script_changed");
- undo_redo->add_undo_method(this, "emit_signal", "script_changed");
+ undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
+ undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
// _update_graph();
@@ -903,8 +903,8 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
- undo_redo->add_do_method(this, "emit_signal", "script_changed");
- undo_redo->add_undo_method(this, "emit_signal", "script_changed");
+ undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
+ undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
return; //or crash because it will become invalid
@@ -918,8 +918,8 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(script.ptr(), "rename_custom_signal", new_name, name);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
- undo_redo->add_do_method(this, "emit_signal", "script_changed");
- undo_redo->add_undo_method(this, "emit_signal", "script_changed");
+ undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
+ undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
return; //or crash because it will become invalid
@@ -1057,8 +1057,8 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
undo_redo->add_undo_method(this, "_update_members");
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
- undo_redo->add_do_method(this, "emit_signal", "script_changed");
- undo_redo->add_undo_method(this, "emit_signal", "script_changed");
+ undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
+ undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
_update_graph();
@@ -1077,8 +1077,8 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
undo_redo->add_undo_method(script.ptr(), "remove_variable", name);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
- undo_redo->add_do_method(this, "emit_signal", "script_changed");
- undo_redo->add_undo_method(this, "emit_signal", "script_changed");
+ undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
+ undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
return; //or crash because it will become invalid
}
@@ -1093,8 +1093,8 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
undo_redo->add_undo_method(script.ptr(), "remove_custom_signal", name);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
- undo_redo->add_do_method(this, "emit_signal", "script_changed");
- undo_redo->add_undo_method(this, "emit_signal", "script_changed");
+ undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
+ undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
return; //or crash because it will become invalid
}
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index 6bd052fe26..d0e9b5bb86 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -1179,7 +1179,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
if (expression[next_op + 1].is_op) {
// this is not invalid and can really appear
// but it becomes invalid anyway because no binary op
- // can be followed by an unary op in a valid combination,
+ // can be followed by a unary op in a valid combination,
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators.");
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index af7b334e46..1decc004ab 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -2702,7 +2702,10 @@ void VisualScriptCustomNode::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_working_memory_size"));
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_step:Variant", PropertyInfo(Variant::ARRAY, "inputs"), PropertyInfo(Variant::ARRAY, "outputs"), PropertyInfo(Variant::INT, "start_mode"), PropertyInfo(Variant::ARRAY, "working_mem")));
+
+ MethodInfo stepmi(Variant::NIL, "_step", PropertyInfo(Variant::ARRAY, "inputs"), PropertyInfo(Variant::ARRAY, "outputs"), PropertyInfo(Variant::INT, "start_mode"), PropertyInfo(Variant::ARRAY, "working_mem"));
+ stepmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ BIND_VMETHOD(stepmi);
ClassDB::bind_method(D_METHOD("_script_changed"), &VisualScriptCustomNode::_script_changed);
@@ -2839,7 +2842,9 @@ VisualScriptNodeInstance *VisualScriptSubCall::instance(VisualScriptInstance *p_
void VisualScriptSubCall::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_subcall:Variant", PropertyInfo(Variant::NIL, "arguments:Variant")));
+ MethodInfo scmi(Variant::NIL, "_subcall", PropertyInfo(Variant::NIL, "arguments"));
+ scmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ BIND_VMETHOD(scmi);
}
VisualScriptSubCall::VisualScriptSubCall() {
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index 694fb96cfa..421409b265 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* visual_script_nodes.h */
+/* visual_script_nodes.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index 4b8e17421b..b6d4021ca3 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -516,7 +516,7 @@ public:
} else {
//yield
- Object *object;
+ Object *object = NULL;
switch (call_mode) {
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 26344877de..0178ebab84 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* av_stream_webm.cpp.cpp */
+/* video_stream_webm.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h
index a48a6c6b9a..9a331849be 100644
--- a/modules/webm/video_stream_webm.h
+++ b/modules/webm/video_stream_webm.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* av_stream_webm.cpp.cpp */
+/* video_stream_webm.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index e774f5bb7d..9ebed84ace 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* audio_driver_opensl.cpp */
+/* audio_driver_opensl.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 65442bf6f8..c1ac54c587 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -240,7 +240,7 @@ def configure(env):
env.Append(CPPPATH=['#platform/android'])
env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT'])
- env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z'])
+ env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z', 'dl'])
# TODO: Move that to opus module's config
if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"):
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index eff3a7178d..d691bd7629 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -204,7 +204,7 @@ class EditorExportAndroid : public EditorExportPlatform {
String id;
String name;
String description;
- int release;
+ int api_level;
};
struct APKExportData {
@@ -278,7 +278,7 @@ class EditorExportAndroid : public EditorExportPlatform {
if (ea->devices[j].id == ldevices[i]) {
d.description = ea->devices[j].description;
d.name = ea->devices[j].name;
- d.release = ea->devices[j].release;
+ d.api_level = ea->devices[j].api_level;
}
}
@@ -299,7 +299,7 @@ class EditorExportAndroid : public EditorExportPlatform {
String vendor;
String device;
d.description + "Device ID: " + d.id + "\n";
- d.release = 0;
+ d.api_level = 0;
for (int j = 0; j < props.size(); j++) {
String p = props[j];
@@ -310,9 +310,9 @@ class EditorExportAndroid : public EditorExportPlatform {
} else if (p.begins_with("ro.build.display.id=")) {
d.description += "Build: " + p.get_slice("=", 1).strip_edges() + "\n";
} else if (p.begins_with("ro.build.version.release=")) {
- const String release_str = p.get_slice("=", 1).strip_edges();
- d.description += "Release: " + release_str + "\n";
- d.release = release_str.to_int();
+ d.description += "Release: " + p.get_slice("=", 1).strip_edges() + "\n";
+ } else if (p.begins_with("ro.build.version.sdk=")) {
+ d.api_level = p.get_slice("=", 1).to_int();
} else if (p.begins_with("ro.product.cpu.abi=")) {
d.description += "CPU: " + p.get_slice("=", 1).strip_edges() + "\n";
} else if (p.begins_with("ro.product.manufacturer=")) {
@@ -468,11 +468,36 @@ class EditorExportAndroid : public EditorExportPlatform {
return zipfi;
}
- static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+ static Set<String> get_abis() {
+ Set<String> abis;
+ abis.insert("armeabi");
+ abis.insert("armeabi-v7a");
+ abis.insert("arm64-v8a");
+ abis.insert("x86");
+ abis.insert("x86_64");
+ abis.insert("mips");
+ abis.insert("mips64");
+ return abis;
+ }
+ static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
APKExportData *ed = (APKExportData *)p_userdata;
String dst_path = p_path;
- dst_path = dst_path.replace_first("res://", "assets/");
+ static Set<String> android_abis = get_abis();
+
+ if (dst_path.ends_with(".so")) {
+ String abi = dst_path.get_base_dir().get_file().strip_edges(); // parent dir name
+ if (android_abis.has(abi)) {
+ dst_path = "lib/" + abi + "/" + dst_path.get_file();
+ } else {
+ String err = "Dynamic libraries must be located in the folder named after Android ABI they were compiled for. " +
+ p_path + " does not follow this convention.";
+ ERR_PRINT(err.utf8().get_data());
+ return ERR_FILE_BAD_PATH;
+ }
+ } else {
+ dst_path = dst_path.replace_first("res://", "assets/");
+ }
zip_fileinfo zipfi = get_zip_fileinfo();
@@ -515,14 +540,14 @@ class EditorExportAndroid : public EditorExportPlatform {
//print_line("FILESIZE: "+itos(filesize)+" ACTUAL: "+itos(p_manifest.size()));
- uint32_t string_count;
- uint32_t styles_count;
- uint32_t string_flags;
- uint32_t string_data_offset;
+ uint32_t string_count = 0;
+ uint32_t styles_count = 0;
+ uint32_t string_flags = 0;
+ uint32_t string_data_offset = 0;
- uint32_t styles_offset;
- uint32_t string_table_begins;
- uint32_t string_table_ends;
+ uint32_t styles_offset = 0;
+ uint32_t string_table_begins = 0;
+ uint32_t string_table_ends = 0;
Vector<uint8_t> stable_extra;
String version_name = p_preset->get("version/name");
@@ -1073,11 +1098,11 @@ public:
//export_temp
ep.step("Exporting APK", 0);
- bool use_adb_over_usb = bool(EDITOR_DEF("export/android/use_remote_debug_over_adb", true));
+ const bool use_remote = (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) || (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT);
+ const bool use_reverse = devices[p_device].api_level >= 21;
- if (use_adb_over_usb) {
+ if (use_reverse)
p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST;
- }
String export_to = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpexport.apk";
Error err = export_project(p_preset, true, export_to, p_debug_flags);
@@ -1123,37 +1148,54 @@ public:
return ERR_CANT_CREATE;
}
- if (use_adb_over_usb) {
+ if (use_remote) {
+ if (use_reverse) {
- args.clear();
- args.push_back("-s");
- args.push_back(devices[p_device].id);
- args.push_back("reverse");
- args.push_back("--remove-all");
- OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
+ static const char *const msg = "** Device API >= 21; debugging over USB **";
+ EditorNode::get_singleton()->get_log()->add_message(msg);
+ print_line(String(msg).to_upper());
- int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port");
- args.clear();
- args.push_back("-s");
- args.push_back(devices[p_device].id);
- args.push_back("reverse");
- args.push_back("tcp:" + itos(dbg_port));
- args.push_back("tcp:" + itos(dbg_port));
+ args.clear();
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
+ args.push_back("reverse");
+ args.push_back("--remove-all");
+ OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
- OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
- print_line("Reverse result: " + itos(rv));
+ if (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) {
- int fs_port = EditorSettings::get_singleton()->get("filesystem/file_server/port");
+ int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port");
+ args.clear();
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
+ args.push_back("reverse");
+ args.push_back("tcp:" + itos(dbg_port));
+ args.push_back("tcp:" + itos(dbg_port));
- args.clear();
- args.push_back("-s");
- args.push_back(devices[p_device].id);
- args.push_back("reverse");
- args.push_back("tcp:" + itos(fs_port));
- args.push_back("tcp:" + itos(fs_port));
+ OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
+ print_line("Reverse result: " + itos(rv));
+ }
- err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
- print_line("Reverse result2: " + itos(rv));
+ if (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT) {
+
+ int fs_port = EditorSettings::get_singleton()->get("filesystem/file_server/port");
+
+ args.clear();
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
+ args.push_back("reverse");
+ args.push_back("tcp:" + itos(fs_port));
+ args.push_back("tcp:" + itos(fs_port));
+
+ err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
+ print_line("Reverse result2: " + itos(rv));
+ }
+ } else {
+
+ static const char *const msg = "** Device API < 21; debugging over Wi-Fi **";
+ EditorNode::get_singleton()->get_log()->add_message(msg);
+ print_line(String(msg).to_upper());
+ }
}
ep.step("Running on Device..", 3);
@@ -1163,7 +1205,7 @@ public:
args.push_back("shell");
args.push_back("am");
args.push_back("start");
- if ((bool)EditorSettings::get_singleton()->get("export/android/force_system_user") && devices[p_device].release >= 17) { // Multi-user introduced in Android 17
+ if ((bool)EditorSettings::get_singleton()->get("export/android/force_system_user") && devices[p_device].api_level >= 17) { // Multi-user introduced in Android 17
args.push_back("--user");
args.push_back("0");
}
@@ -1294,7 +1336,7 @@ public:
bool export_arm = p_preset->get("architecture/arm");
bool export_arm64 = p_preset->get("architecture/arm64");
- bool use_32_fb = p_preset->get("screen/use_32_bits_view");
+ bool use_32_fb = p_preset->get("graphics/32_bits_framebuffer");
bool immersive = p_preset->get("screen/immersive_mode");
bool _signed = p_preset->get("package/signed");
@@ -1376,15 +1418,15 @@ public:
}
}
- if (file == "lib/x86/libgodot_android.so" && !export_x86) {
+ if (file == "lib/x86/*.so" && !export_x86) {
skip = true;
}
- if (file.match("lib/armeabi*/libgodot_android.so") && !export_arm) {
+ if (file.match("lib/armeabi*/*.so") && !export_arm) {
skip = true;
}
- if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) {
+ if (file.match("lib/arm64*/*.so") && !export_arm64) {
skip = true;
}
@@ -1724,7 +1766,6 @@ void register_android_exporter() {
EDITOR_DEF("export/android/force_system_user", false);
EDITOR_DEF("export/android/timestamping_authority_url", "");
- EDITOR_DEF("export/android/use_remote_debug_over_adb", false);
EDITOR_DEF("export/android/shutdown_adb_on_exit", true);
Ref<EditorExportAndroid> exporter = Ref<EditorExportAndroid>(memnew(EditorExportAndroid));
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index eab0387f32..53a90e4cfe 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -92,7 +92,7 @@ import android.os.SystemClock;
public class Godot extends Activity implements SensorEventListener, IDownloaderClient
-{
+{
static final int MAX_SINGLETONS = 64;
private IStub mDownloaderClientStub;
@@ -139,9 +139,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
com.godot.game.R.string.text_button_pause;
mPauseButton.setText(stringResourceID);
}
-
+
static public class SingletonBase {
-
+
protected void registerClass(String p_name, String[] p_methods) {
GodotLib.singleton(p_name,this);
@@ -210,6 +210,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
*/
private String[] command_line;
+ private boolean use_apk_expansion;
public GodotView mView;
private boolean godot_initialized=false;
@@ -264,27 +265,40 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
layout = new FrameLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
setContentView(layout);
-
+
// GodotEditText layout
- GodotEditText edittext = new GodotEditText(this);
+ GodotEditText edittext = new GodotEditText(this);
edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
// ...add to FrameLayout
layout.addView(edittext);
-
+
mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this);
layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
- setKeepScreenOn(GodotLib.getGlobal("display/driver/keep_screen_on").equals("True"));
-
- edittext.setView(mView);
- io.setEdit(edittext);
-
+ edittext.setView(mView);
+ io.setEdit(edittext);
+
// Ad layout
adLayout = new RelativeLayout(this);
adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
layout.addView(adLayout);
-
+
+ final String[] current_command_line = command_line;
+ final GodotView view = mView;
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.setup(current_command_line);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/driver/keep_screen_on")));
+ }
+ });
+ }
+ });
+
}
-
+
public void setKeepScreenOn(final boolean p_enabled) {
keep_screen_on = p_enabled;
if (mView != null){
@@ -315,13 +329,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
});
}
-
+
private static Godot _self;
-
+
public static Godot getInstance(){
return Godot._self;
}
-
+
private String[] getCommandLine() {
InputStream is;
@@ -402,7 +416,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
Log.d("GODOT"," " + command_line[w]);
}
}*/
- GodotLib.initialize(this,io.needsReloadHooks(),command_line,getAssets());
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
@@ -411,9 +424,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
+ GodotLib.initialize(this, io.needsReloadHooks(), getAssets(), use_apk_expansion);
+
result_callback = null;
mPaymentsManager = PaymentsManager.createManager(this).initService();
+
godot_initialized=true;
}
@@ -426,7 +442,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
- @Override
+ @Override
protected void onCreate(Bundle icicle) {
Log.d("GODOT", "** GODOT ACTIVITY CREATED HERE ***\n");
@@ -437,12 +453,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
//window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
-
//check for apk expansion API
if (true) {
boolean md5mismatch = false;
command_line = getCommandLine();
- boolean use_apk_expansion=false;
String main_pack_md5=null;
String main_pack_key=null;
@@ -528,23 +542,23 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
if (!pack_valid) {
Log.d("GODOT", "Pack Invalid, try re-downloading.");
-
+
Intent notifierIntent = new Intent(this, this.getClass());
notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
-
+
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
+
int startResult;
try {
Log.d("GODOT", "INITIALIZING DOWNLOAD");
startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
- getApplicationContext(),
- pendingIntent,
+ getApplicationContext(),
+ pendingIntent,
GodotDownloaderService.class);
Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult);
-
+
if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
Log.d("GODOT", "DOWNLOAD REQUIRED");
// This is where you do set up to display the download
@@ -563,7 +577,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mCellMessage = findViewById(com.godot.game.R.id.approveCellular);
mPauseButton = (Button) findViewById(com.godot.game.R.id.pauseButton);
mWiFiSettingsButton = (Button) findViewById(com.godot.game.R.id.wifiSettingsButton);
-
+
return;
} else{
Log.d("GODOT", "NO DOWNLOAD REQUIRED");
@@ -582,7 +596,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
initializeGodot();
-
+
//instanceSingleton( new GodotFacebook(this) );
@@ -590,14 +604,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override protected void onDestroy(){
-
+
if(mPaymentsManager != null ) mPaymentsManager.destroy();
for(int i=0;i<singleton_count;i++) {
singletons[i].onMainDestroy();
}
super.onDestroy();
}
-
+
@Override protected void onPause() {
super.onPause();
if (!godot_initialized){
@@ -607,8 +621,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
return;
}
mView.onPause();
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.focusout();
+ }
+ });
mSensorManager.unregisterListener(this);
- GodotLib.focusout();
for(int i=0;i<singleton_count;i++) {
singletons[i].onMainPause();
@@ -625,10 +644,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
mView.onResume();
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.focusin();
+ }
+ });
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
- GodotLib.focusin();
+
if(use_immersive && Build.VERSION.SDK_INT >= 19.0){ // check if the application runs on an android 4.4+
Window window = getWindow();
window.getDecorView().setSystemUiVisibility(
@@ -644,8 +669,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
singletons[i].onMainResume();
}
-
-
+
+
}
@@ -670,32 +695,39 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override public void onSensorChanged(SensorEvent event) {
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int displayRotation = display.getRotation();
-
+
float[] adjustedValues = new float[3];
final int axisSwap[][] = {
- { 1, -1, 0, 1 }, // ROTATION_0
- {-1, -1, 1, 0 }, // ROTATION_90
- {-1, 1, 0, 1 }, // ROTATION_180
- { 1, 1, 1, 0 } }; // ROTATION_270
-
- final int[] as = axisSwap[displayRotation];
- adjustedValues[0] = (float)as[0] * event.values[ as[2] ];
- adjustedValues[1] = (float)as[1] * event.values[ as[3] ];
+ { 1, -1, 0, 1 }, // ROTATION_0
+ {-1, -1, 1, 0 }, // ROTATION_90
+ {-1, 1, 0, 1 }, // ROTATION_180
+ { 1, 1, 1, 0 } }; // ROTATION_270
+
+ final int[] as = axisSwap[displayRotation];
+ adjustedValues[0] = (float)as[0] * event.values[ as[2] ];
+ adjustedValues[1] = (float)as[1] * event.values[ as[3] ];
adjustedValues[2] = event.values[2];
-
- float x = adjustedValues[0];
- float y = adjustedValues[1];
- float z = adjustedValues[2];
-
- int typeOfSensor = event.sensor.getType();
- if (typeOfSensor == event.sensor.TYPE_ACCELEROMETER) {
- GodotLib.accelerometer(x,y,z);
- }
- if (typeOfSensor == event.sensor.TYPE_MAGNETIC_FIELD) {
- GodotLib.magnetometer(x,y,z);
- }
- if (typeOfSensor == event.sensor.TYPE_GYROSCOPE) {
- GodotLib.gyroscope(x,y,z);
+
+ final float x = adjustedValues[0];
+ final float y = adjustedValues[1];
+ final float z = adjustedValues[2];
+
+ final int typeOfSensor = event.sensor.getType();
+ if (mView != null) {
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) {
+ GodotLib.accelerometer(x,y,z);
+ }
+ if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) {
+ GodotLib.magnetometer(x,y,z);
+ }
+ if (typeOfSensor == Sensor.TYPE_GYROSCOPE) {
+ GodotLib.gyroscope(x,y,z);
+ }
+ }
+ });
}
}
@@ -722,7 +754,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override public void onBackPressed() {
System.out.printf("** BACK REQUEST!\n");
- //GodotLib.back();
+ if (mView != null) {
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.back();
+ }
+ });
+ }
}
public void forceQuit() {
@@ -733,7 +772,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private boolean obbIsCorrupted(String f, String main_pack_md5){
-
+
try {
InputStream fis = new FileInputStream(f);
@@ -780,58 +819,64 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
//@Override public boolean dispatchTouchEvent (MotionEvent event) {
- public boolean gotTouchEvent(MotionEvent event) {
+ public boolean gotTouchEvent(final MotionEvent event) {
super.onTouchEvent(event);
- int evcount=event.getPointerCount();
+ final int evcount=event.getPointerCount();
if (evcount==0)
return true;
- int[] arr = new int[event.getPointerCount()*3];
+ if (mView != null) {
+ final int[] arr = new int[event.getPointerCount()*3];
- for(int i=0;i<event.getPointerCount();i++) {
+ for(int i=0;i<event.getPointerCount();i++) {
- arr[i*3+0]=(int)event.getPointerId(i);
- arr[i*3+1]=(int)event.getX(i);
- arr[i*3+2]=(int)event.getY(i);
- }
+ arr[i*3+0]=(int)event.getPointerId(i);
+ arr[i*3+1]=(int)event.getX(i);
+ arr[i*3+2]=(int)event.getY(i);
+ }
- //System.out.printf("gaction: %d\n",event.getAction());
- switch(event.getAction()&MotionEvent.ACTION_MASK) {
-
- case MotionEvent.ACTION_DOWN: {
- GodotLib.touch(0,0,evcount,arr);
- //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
- } break;
- case MotionEvent.ACTION_MOVE: {
- GodotLib.touch(1,0,evcount,arr);
- /*
- for(int i=0;i<event.getPointerCount();i++) {
- System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
- }
- */
- } break;
- case MotionEvent.ACTION_POINTER_UP: {
- final int indexPointUp = event.getActionIndex();
- final int pointer_idx = event.getPointerId(indexPointUp);
- GodotLib.touch(4,pointer_idx,evcount,arr);
- //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
- } break;
- case MotionEvent.ACTION_POINTER_DOWN: {
- int pointer_idx = event.getActionIndex();
- GodotLib.touch(3,pointer_idx,evcount,arr);
- //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
- } break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP: {
- GodotLib.touch(2,0,evcount,arr);
- /*
- for(int i=0;i<event.getPointerCount();i++) {
- System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
+ //System.out.printf("gaction: %d\n",event.getAction());
+ final int action = event.getAction() & MotionEvent.ACTION_MASK;
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ switch(action) {
+ case MotionEvent.ACTION_DOWN: {
+ GodotLib.touch(0,0,evcount,arr);
+ //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
+ } break;
+ case MotionEvent.ACTION_MOVE: {
+ GodotLib.touch(1,0,evcount,arr);
+ /*
+ for(int i=0;i<event.getPointerCount();i++) {
+ System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
+ }
+ */
+ } break;
+ case MotionEvent.ACTION_POINTER_UP: {
+ final int indexPointUp = event.getActionIndex();
+ final int pointer_idx = event.getPointerId(indexPointUp);
+ GodotLib.touch(4,pointer_idx,evcount,arr);
+ //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
+ } break;
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ int pointer_idx = event.getActionIndex();
+ GodotLib.touch(3,pointer_idx,evcount,arr);
+ //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
+ } break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP: {
+ GodotLib.touch(2,0,evcount,arr);
+ /*
+ for(int i=0;i<event.getPointerCount();i++) {
+ System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
+ }
+ */
+ } break;
+ }
}
- */
- } break;
-
+ });
}
return true;
}
@@ -864,7 +909,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private void queueEvent(Runnable runnable) {
// TODO Auto-generated method stub
-
+
}
public PaymentsManager getPaymentsManager() {
@@ -988,7 +1033,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mProgressFraction.setText(Helpers.getDownloadProgressString
(progress.mOverallProgress,
progress.mOverallTotal));
-
+
}
-
+
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java
index b487c17f53..47a690140f 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java
@@ -37,7 +37,7 @@ public class GodotLib {
public static GodotIO io;
static {
- System.loadLibrary("godot_android");
+ System.loadLibrary("godot_android");
}
/**
@@ -45,7 +45,8 @@ public class GodotLib {
* @param height the current view height
*/
- public static native void initialize(Godot p_instance,boolean need_reload_hook,String[] p_cmdline,Object p_asset_manager);
+ public static native void initialize(Godot p_instance,boolean need_reload_hook,Object p_asset_manager, boolean use_apk_expansion);
+ public static native void setup(String[] p_cmdline);
public static native void resize(int width, int height,boolean reload);
public static native void newcontext(boolean p_32_bits);
public static native void back();
diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
index a16c67523e..8fe79fdfc7 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
@@ -89,7 +89,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
}
public void callbackSuccess(String ticket, String signature, String sku) {
- GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku});
+ GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku});
}
public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku) {
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index 19fcf8e687..3c2ad7cc59 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -208,8 +208,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
@Override public void onInputDeviceAdded(int deviceId) {
joystick joy = new joystick();
joy.device_id = deviceId;
- int id = joy_devices.size();
+ final int id = joy_devices.size();
InputDevice device = mInputManager.getInputDevice(deviceId);
+ final String name = device.getName();
joy.name = device.getName();
joy.axes = new ArrayList<InputDevice.MotionRange>();
joy.hats = new ArrayList<InputDevice.MotionRange>();
@@ -224,19 +225,29 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
}
}
joy_devices.add(joy);
- GodotLib.joyconnectionchanged(id, true, joy.name);
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(id, true, name);
+ }
+ });
}
@Override public void onInputDeviceRemoved(int deviceId) {
- int id = find_joy_device(deviceId);
+ final int id = find_joy_device(deviceId);
joy_devices.remove(id);
- GodotLib.joyconnectionchanged(id, false, "");
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(id, false, "");
+ }
+ });
}
@Override public void onInputDeviceChanged(int deviceId) {
}
- @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
+ @Override public boolean onKeyUp(final int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
@@ -249,22 +260,38 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
int source = event.getSource();
if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) {
- int button = get_godot_button(keyCode);
- int device = find_joy_device(event.getDeviceId());
+ final int button = get_godot_button(keyCode);
+ final int device = find_joy_device(event.getDeviceId());
- GodotLib.joybutton(device, button, false);
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joybutton(device, button, false);
+ }
+ });
return true;
} else {
-
- GodotLib.key(keyCode, event.getUnicodeChar(0), false);
+ final int chr = event.getUnicodeChar(0);
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.key(keyCode, chr, false);
+ }
+ });
};
return super.onKeyUp(keyCode, event);
};
- @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+ @Override public boolean onKeyDown(final int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- GodotLib.back();
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.back();
+ }
+ });
+
// press 'back' button should not terminate program
//normal handle 'back' event in game logic
return true;
@@ -281,16 +308,26 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
if (event.getRepeatCount() > 0) // ignore key echo
return true;
- int button = get_godot_button(keyCode);
- int device = find_joy_device(event.getDeviceId());
+ final int button = get_godot_button(keyCode);
+ final int device = find_joy_device(event.getDeviceId());
//Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device));
-
- GodotLib.joybutton(device, button, true);
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joybutton(device, button, true);
+ }
+ });
return true;
} else {
- GodotLib.key(keyCode, event.getUnicodeChar(0), true);
+ final int chr = event.getUnicodeChar(0);
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.key(keyCode, chr, true);
+ }
+ });
};
return super.onKeyDown(keyCode, event);
}
@@ -299,21 +336,32 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
- int device_id = find_joy_device(event.getDeviceId());
+ final int device_id = find_joy_device(event.getDeviceId());
joystick joy = joy_devices.get(device_id);
for (int i = 0; i < joy.axes.size(); i++) {
InputDevice.MotionRange range = joy.axes.get(i);
- float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
+ final float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
//Log.e(TAG, String.format("axis event: %d, value %f", i, value));
- GodotLib.joyaxis(device_id, i, value);
+ final int idx = i;
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyaxis(device_id, idx, value);
+ }
+ });
}
for (int i = 0; i < joy.hats.size(); i+=2) {
- int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
- int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis()));
+ final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
+ final int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis()));
//Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY));
- GodotLib.joyhat(device_id, hatX, hatY);
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyhat(device_id, hatX, hatY);
+ }
+ });
}
return true;
};
diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index c2d03e4ecc..04669a3b0c 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -89,8 +89,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
//Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after);
for (int i=0;i<count;i++){
- GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true);
- GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false);
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false);
+ }
+ });
}
}
@@ -99,9 +104,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
//Log.d(TAG, "onTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",before: " + before);
for (int i=start;i<start+count;i++){
- int ch = pCharSequence.charAt(i);
- GodotLib.key(0, ch, true);
- GodotLib.key(0, ch, false);
+ final int ch = pCharSequence.charAt(i);
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.key(0, ch, true);
+ GodotLib.key(0, ch, false);
+ }
+ });
}
}
@@ -111,8 +121,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
if (this.mEdit == pTextView && this.isFullScreenEdit()) {
// user press the action button, delete all old text and insert new text
for (int i = this.mOriginText.length(); i > 0; i--) {
- GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true);
- GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false);
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false);
+ }
+ });
+
/*
if (BuildConfig.DEBUG) {
Log.d(TAG, "deleteBackward");
@@ -131,9 +147,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
}
for(int i = 0; i < text.length(); i++) {
- int ch = text.codePointAt(i);
- GodotLib.key(0, ch, true);
- GodotLib.key(0, ch, false);
+ final int ch = text.codePointAt(i);
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.key(0, ch, true);
+ GodotLib.key(0, ch, false);
+ }
+ });
}
/*
if (BuildConfig.DEBUG) {
@@ -141,7 +162,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
}
*/
}
-
+
if (pActionID == EditorInfo.IME_ACTION_DONE) {
this.mView.requestFocus();
}
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 9abaae0a75..509d1bf123 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -613,8 +613,6 @@ static List<JAndroidPointerEvent> pointer_events;
static List<Ref<InputEvent> > key_events;
static List<OS_Android::JoypadEvent> joy_events;
static bool initialized = false;
-static Mutex *input_mutex = NULL;
-static Mutex *suspend_mutex = NULL;
static int step = 0;
static bool resized = false;
static bool resized_reload = false;
@@ -756,7 +754,7 @@ static void _alert(const String &p_message, const String &p_title) {
env->CallVoidMethod(_godot_instance, _alertDialog, jStrMessage, jStrTitle);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobjectArray p_cmdline, jobject p_asset_manager) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion) {
__android_log_print(ANDROID_LOG_INFO, "godot", "**INIT EVENT! - %p\n", env);
@@ -826,36 +824,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
AudioDriverAndroid::setup(gob);
}
- const char **cmdline = NULL;
- int cmdlen = 0;
- bool use_apk_expansion = false;
- if (p_cmdline) {
- cmdlen = env->GetArrayLength(p_cmdline);
- if (cmdlen) {
- cmdline = (const char **)malloc((env->GetArrayLength(p_cmdline) + 1) * sizeof(const char *));
- cmdline[cmdlen] = NULL;
-
- for (int i = 0; i < cmdlen; i++) {
-
- jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i);
- const char *rawString = env->GetStringUTFChars(string, 0);
- if (!rawString) {
- __android_log_print(ANDROID_LOG_INFO, "godot", "cmdline arg %i is null\n", i);
- } else {
- //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString);
-
- if (strcmp(rawString, "--main_pack") == 0)
- use_apk_expansion = true;
- }
-
- cmdline[i] = rawString;
- }
- }
- }
-
- __android_log_print(ANDROID_LOG_INFO, "godot", "CMDLINE LEN %i - APK EXPANSION %I\n", cmdlen, int(use_apk_expansion));
-
- os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, use_apk_expansion);
+ os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion);
os_android->set_need_reload_hooks(p_need_reload_hook);
char wd[500];
@@ -864,62 +833,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
__android_log_print(ANDROID_LOG_INFO, "godot", "test construction %i\n", tst.a);
__android_log_print(ANDROID_LOG_INFO, "godot", "running from dir %s\n", wd);
- __android_log_print(ANDROID_LOG_INFO, "godot", "**SETUP");
-
- Error err = Main::setup("apk", cmdlen, (char **)cmdline, false);
-
- if (err != OK) {
- __android_log_print(ANDROID_LOG_INFO, "godot", "*****UNABLE TO SETUP");
-
- return; //should exit instead and print the error
- }
-
- __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK");
-
//video driver is determined here, because once initialized, it can't be changed
- String vd = ProjectSettings::get_singleton()->get("display/driver");
+ // String vd = ProjectSettings::get_singleton()->get("display/driver");
env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean) true);
-
- __android_log_print(ANDROID_LOG_INFO, "godot", "**START");
-
- input_mutex = Mutex::create();
- suspend_mutex = Mutex::create();
-}
-
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) {
-
- __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height);
- if (os_android)
- os_android->set_display_size(Size2(width, height));
-
- /*input_mutex->lock();
- resized=true;
- if (reload)
- resized_reload=true;
- new_size=Size2(width,height);
- input_mutex->unlock();*/
-}
-
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) {
-
- __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id());
-
- if (os_android) {
- os_android->set_context_is_16_bits(!p_32_bits);
- }
-
- if (os_android && step > 0) {
-
- os_android->reload_gfx();
- }
-}
-
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) {
-
- input_mutex->lock();
- go_back_request = true;
- input_mutex->unlock();
}
static void _initialize_java_modules() {
@@ -985,34 +902,106 @@ static void _initialize_java_modules() {
}
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj) {
-
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline) {
ThreadAndroid::setup_thread();
- //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id());
+ __android_log_print(ANDROID_LOG_INFO, "godot", "**SETUP");
- suspend_mutex->lock();
- input_mutex->lock();
- //first time step happens, initialize
- if (step == 0) {
- // ugly hack to initialize the rest of the engine
- // because of the way android forces you to do everything with threads
+ const char **cmdline = NULL;
+ int cmdlen = 0;
+ bool use_apk_expansion = false;
+ if (p_cmdline) {
+ cmdlen = env->GetArrayLength(p_cmdline);
+ if (cmdlen) {
+ cmdline = (const char **)malloc((env->GetArrayLength(p_cmdline) + 1) * sizeof(const char *));
+ cmdline[cmdlen] = NULL;
+
+ for (int i = 0; i < cmdlen; i++) {
+
+ jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i);
+ const char *rawString = env->GetStringUTFChars(string, 0);
+ if (!rawString) {
+ __android_log_print(ANDROID_LOG_INFO, "godot", "cmdline arg %i is null\n", i);
+ } else {
+ //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString);
- java_class_wrapper = memnew(JavaClassWrapper(_godot_instance));
- ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaClassWrapper", java_class_wrapper));
- _initialize_java_modules();
+ if (strcmp(rawString, "-main_pack") == 0)
+ use_apk_expansion = true;
+ }
- Main::setup2();
+ cmdline[i] = rawString;
+ }
+ }
+ }
+ __android_log_print(ANDROID_LOG_INFO, "godot", "CMDLINE LEN %i - APK EXPANSION %i\n", cmdlen, int(use_apk_expansion));
+
+#if 0
+ char *args[]={"-test","render",NULL};
+ __android_log_print(ANDROID_LOG_INFO,"godot","pre asdasd setup...");
+ Error err = Main::setup("apk",2,args,false);
+#else
+ Error err = Main::setup("apk", cmdlen, (char **)cmdline, false);
+#endif
+ if (cmdline) {
+ free(cmdline);
+ }
+
+ if (err != OK) {
+ __android_log_print(ANDROID_LOG_INFO, "godot", "*****UNABLE TO SETUP");
+ return; //should exit instead and print the error
+ }
+ __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK");
+
+ java_class_wrapper = memnew(JavaClassWrapper(_godot_instance));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaClassWrapper", java_class_wrapper));
+ _initialize_java_modules();
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) {
+
+ __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height);
+ if (os_android)
+ os_android->set_display_size(Size2(width, height));
+
+ /*input_mutex->lock();
+ resized=true;
+ if (reload)
+ resized_reload=true;
+ new_size=Size2(width,height);
+ input_mutex->unlock();*/
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) {
+
+ __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id());
+
+ if (os_android) {
+ os_android->set_context_is_16_bits(!p_32_bits);
+ }
+
+ if (os_android && step > 0) {
+
+ os_android->reload_gfx();
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) {
+ go_back_request = true;
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj) {
+ if (step == 0) {
+ __android_log_print(ANDROID_LOG_INFO, "godot", "**FIRST_STEP");
+
+ // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id,
+ // but for Godot purposes, the main thread is the one running the game loop
+ Main::setup2(Thread::get_caller_id());
++step;
- suspend_mutex->unlock();
- input_mutex->unlock();
return;
- };
+ }
+
if (step == 1) {
if (!Main::start()) {
-
- input_mutex->unlock();
- suspend_mutex->lock();
return; //should exit instead and print the error
}
@@ -1020,6 +1009,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
++step;
}
+ //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id());
+
while (pointer_events.size()) {
JAndroidPointerEvent jpe = pointer_events.front()->get();
@@ -1050,8 +1041,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
go_back_request = false;
}
- input_mutex->unlock();
-
os_android->process_accelerometer(accelerometer);
os_android->process_magnetometer(magnetometer);
@@ -1065,8 +1054,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
env->CallVoidMethod(_godot_instance, _finish);
__android_log_print(ANDROID_LOG_INFO, "godot", "**FINISH REQUEST!!! - %p-%i\n", env, Thread::get_caller_id());
}
-
- suspend_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) {
@@ -1089,11 +1076,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jo
jpe.points = points;
jpe.what = ev;
- input_mutex->lock();
-
pointer_events.push_back(jpe);
-
- input_mutex->unlock();
/*
if (os_android)
os_android->process_touch(ev,pointer,points);
@@ -1363,9 +1346,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env
jevent.index = p_button;
jevent.pressed = p_pressed;
- input_mutex->lock();
joy_events.push_back(jevent);
- input_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value) {
@@ -1376,9 +1357,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env,
jevent.index = p_axis;
jevent.value = p_value;
- input_mutex->lock();
joy_events.push_back(jevent);
- input_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) {
@@ -1399,9 +1378,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j
hat |= InputDefault::HAT_MASK_DOWN;
}
jevent.hat = hat;
- input_mutex->lock();
joy_events.push_back(jevent);
- input_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jobject obj, jint p_device, jboolean p_connected, jstring p_name) {
@@ -1435,54 +1412,31 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobj
go_back_request = true;
}
- input_mutex->lock();
key_events.push_back(ievent);
- input_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) {
-
- input_mutex->lock();
accelerometer = Vector3(x, y, z);
- input_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnetometer(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) {
-
- input_mutex->lock();
magnetometer = Vector3(x, y, z);
- input_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) {
-
- input_mutex->lock();
gyroscope = Vector3(x, y, z);
- input_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jobject obj) {
- if (!suspend_mutex)
- return;
- suspend_mutex->lock();
-
if (os_android && step > 0)
os_android->main_loop_focusin();
-
- suspend_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jobject obj) {
- if (!suspend_mutex)
- return;
- suspend_mutex->lock();
-
if (os_android && step > 0)
os_android->main_loop_focusout();
-
- suspend_mutex->unlock();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jobject obj) {
diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h
index 64970040f8..ec8ae9a0a6 100644
--- a/platform/android/java_glue.h
+++ b/platform/android/java_glue.h
@@ -36,7 +36,8 @@
#include <jni.h>
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobjectArray p_cmdline, jobject p_asset_manager);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj);
diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h
index 7ab3e04bb8..6944ee6749 100644
--- a/platform/iphone/icloud.h
+++ b/platform/iphone/icloud.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* icloud.h */
+/* icloud.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm
index 84458ed79f..097018f296 100644
--- a/platform/iphone/icloud.mm
+++ b/platform/iphone/icloud.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* icloud.mm */
+/* icloud.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index a0e5610591..ac8d367366 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -521,21 +521,6 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
#undef SET_EM_CALLBACK
#undef EM_CHECK
- /* clang-format off */
- EM_ASM_ARGS({
- const send_notification = Module.cwrap('send_notification', null, ['number']);
- const notifs = arguments;
- (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) {
- Module.canvas.addEventListener(event, send_notification.bind(this, notifs[i]));
- });
- },
- MainLoop::NOTIFICATION_WM_MOUSE_ENTER,
- MainLoop::NOTIFICATION_WM_MOUSE_EXIT,
- MainLoop::NOTIFICATION_WM_FOCUS_IN,
- MainLoop::NOTIFICATION_WM_FOCUS_OUT
- );
-/* clang-format on */
-
#ifdef JAVASCRIPT_EVAL_ENABLED
javascript_eval = memnew(JavaScript);
ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaScript", javascript_eval));
@@ -818,7 +803,23 @@ void OS_JavaScript::main_loop_begin() {
if (main_loop)
main_loop->init();
+
+ /* clang-format off */
+ EM_ASM_ARGS({
+ const send_notification = Module.cwrap('send_notification', null, ['number']);
+ const notifs = arguments;
+ (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) {
+ Module.canvas.addEventListener(event, send_notification.bind(null, notifs[i]));
+ });
+ },
+ MainLoop::NOTIFICATION_WM_MOUSE_ENTER,
+ MainLoop::NOTIFICATION_WM_MOUSE_EXIT,
+ MainLoop::NOTIFICATION_WM_FOCUS_IN,
+ MainLoop::NOTIFICATION_WM_FOCUS_OUT
+ );
+ /* clang-format on */
}
+
bool OS_JavaScript::main_loop_iterate() {
if (!main_loop)
diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp
index 8c5a734f76..78c52af201 100644
--- a/platform/osx/audio_driver_osx.cpp
+++ b/platform/osx/audio_driver_osx.cpp
@@ -77,7 +77,7 @@ Error AudioDriverOSX::initDevice() {
break;
}*/
- mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
+ mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
zeromem(&strdesc, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
@@ -92,15 +92,19 @@ Error AudioDriverOSX::initDevice() {
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
- int latency = GLOBAL_DEF("audio/output_latency", 25);
- unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000);
+ int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
+ buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
- if (OS::get_singleton()->is_stdout_verbose()) {
- print_line("audio buffer size: " + itos(buffer_size) + " calculated latency: " + itos(buffer_size * 1000 / mix_rate));
- }
+ result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+ buffer_size = buffer_frames * channels;
samples_in.resize(buffer_size);
- buffer_frames = buffer_size / channels;
+
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ }
AURenderCallbackStruct callback;
zeromem(&callback, sizeof(AURenderCallbackStruct));
@@ -234,7 +238,7 @@ void AudioDriverOSX::start() {
};
int AudioDriverOSX::get_mix_rate() const {
- return 44100;
+ return mix_rate;
};
AudioDriver::SpeakerMode AudioDriverOSX::get_speaker_mode() const {
@@ -282,8 +286,12 @@ AudioDriverOSX::AudioDriverOSX() {
active = false;
mutex = NULL;
- mix_rate = 44100;
+ mix_rate = 0;
channels = 2;
+
+ buffer_size = 0;
+ buffer_frames = 0;
+
samples_in.clear();
};
diff --git a/platform/osx/audio_driver_osx.h b/platform/osx/audio_driver_osx.h
index ac178b89f3..a7e68c8141 100644
--- a/platform/osx/audio_driver_osx.h
+++ b/platform/osx/audio_driver_osx.h
@@ -45,8 +45,9 @@ class AudioDriverOSX : public AudioDriver {
Mutex *mutex;
int mix_rate;
- int channels;
- int buffer_frames;
+ unsigned int channels;
+ unsigned int buffer_frames;
+ unsigned int buffer_size;
Vector<int32_t> samples_in;
diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h
index e271f4b947..4bdef8eb83 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/osx/joypad_osx.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_osx.h */
+/* joypad_osx.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 5bfed1ee50..ebaebd84ce 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -160,6 +160,8 @@ public:
virtual MainLoop *get_main_loop() const;
+ virtual String get_system_dir(SystemDir p_dir) const;
+
virtual bool can_draw() const;
virtual void set_clipboard(const String &p_text);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index f1260bc088..f502fb9a9c 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1327,6 +1327,46 @@ MainLoop *OS_OSX::get_main_loop() const {
return main_loop;
}
+String OS_OSX::get_system_dir(SystemDir p_dir) const {
+
+ NSSearchPathDirectory id = 0;
+
+ switch (p_dir) {
+ case SYSTEM_DIR_DESKTOP: {
+ id = NSDesktopDirectory;
+ } break;
+ case SYSTEM_DIR_DOCUMENTS: {
+ id = NSDocumentDirectory;
+ } break;
+ case SYSTEM_DIR_DOWNLOADS: {
+ id = NSDownloadsDirectory;
+ } break;
+ case SYSTEM_DIR_MOVIES: {
+ id = NSMoviesDirectory;
+ } break;
+ case SYSTEM_DIR_MUSIC: {
+ id = NSMusicDirectory;
+ } break;
+ case SYSTEM_DIR_PICTURES: {
+ id = NSPicturesDirectory;
+ } break;
+ }
+
+ String ret;
+ if (id) {
+
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(id, NSUserDomainMask, YES);
+ if (paths && [paths count] >= 1) {
+
+ char *utfs = strdup([[paths firstObject] UTF8String]);
+ ret.parse_utf8(utfs);
+ free(utfs);
+ }
+ }
+
+ return ret;
+}
+
bool OS_OSX::can_draw() const {
return true;
diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp
index 24591e48b1..5f3938cb91 100644
--- a/platform/osx/power_osx.cpp
+++ b/platform/osx/power_osx.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* power_osx.cpp */
+/* power_osx.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index c129743507..a2be126c58 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -501,7 +501,7 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
size_t block_size = (p_len - step) > BLOCK_SIZE ? BLOCK_SIZE : (p_len - step);
- for (int i = 0; i < block_size; i++) {
+ for (uint32_t i = 0; i < block_size; i++) {
strm_in[i] = p_buffer[step + i];
}
@@ -523,14 +523,14 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
//package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + bh.compressed_size);
- for (int i = 0; i < bh.compressed_size; i++)
+ for (uint32_t i = 0; i < bh.compressed_size; i++)
file_buffer[start + i] = strm_out[i];
} else {
bh.compressed_size = block_size;
//package->store_buffer(strm_in.ptr(), block_size);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + block_size);
- for (int i = 0; i < bh.compressed_size; i++)
+ for (uint32_t i = 0; i < bh.compressed_size; i++)
file_buffer[start + i] = strm_in[i];
}
@@ -553,7 +553,7 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
//package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + (strm.total_out - total_out_before));
- for (int i = 0; i < (strm.total_out - total_out_before); i++)
+ for (uint32_t i = 0; i < (strm.total_out - total_out_before); i++)
file_buffer[start + i] = strm_out[i];
deflateEnd(&strm);
@@ -866,7 +866,7 @@ class EditorExportUWP : public EditorExportPlatform {
Vector<uint8_t> _get_image_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
Vector<uint8_t> data;
- StreamTexture *image;
+ StreamTexture *image = NULL;
if (p_path.find("StoreLogo") != -1) {
image = p_preset->get("images/store_logo").is_zero() ? NULL : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/store_logo")));
@@ -882,6 +882,8 @@ class EditorExportUWP : public EditorExportPlatform {
image = p_preset->get("images/wide310x150_logo").is_zero() ? NULL : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/wide310x150_logo")));
} else if (p_path.find("SplashScreen") != -1) {
image = p_preset->get("images/splash_screen").is_zero() ? NULL : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/splash_screen")));
+ } else {
+ ERR_PRINT("Unable to load logo");
}
if (!image) return data;
diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp
index cde72c98c9..00cfa812de 100644
--- a/platform/windows/joypad.cpp
+++ b/platform/windows/joypad.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad.cpp */
+/* joypad.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/windows/joypad.h b/platform/windows/joypad.h
index 059c577bb6..a76caf6fac 100644
--- a/platform/windows/joypad.h
+++ b/platform/windows/joypad.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad.h */
+/* joypad.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 79778136ad..086681d4a4 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -74,7 +74,9 @@ def configure(env):
## Build type
if (env["target"] == "release"):
- env.Prepend(CCFLAGS=['-Ofast'])
+ # -O3 -ffast-math is identical to -Ofast. We need to split it out so we can selectively disable
+ # -ffast-math in code for which it generates wrong results.
+ env.Prepend(CCFLAGS=['-O3', '-ffast-math'])
if (env["debug_release"] == "yes"):
env.Prepend(CCFLAGS=['-g2'])
@@ -188,6 +190,11 @@ def configure(env):
if any(platform.machine() in s for s in list_of_x86):
env["x86_libtheora_opt_gcc"] = True
+ # On Linux wchar_t should be 32-bits
+ # 16-bit library shouldn't be required due to compiler optimisations
+ if (env['builtin_pcre2'] == 'no'):
+ env.ParseConfig('pkg-config libpcre2-32 --cflags --libs')
+
## Flags
if (os.system("pkg-config --exists alsa") == 0): # 0 means found
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 2d33d25773..f96343c92c 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1237,7 +1237,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
- /* Phase 3, obtain an unicode character from the keysym */
+ /* Phase 3, obtain a unicode character from the keysym */
// KeyMappingX11 also translates keysym to unicode.
// It does a binary search on a table to translate
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index eb186a8e1f..39d3f2d6bf 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -246,12 +246,14 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) {
stream = p_stream;
stream_playback = p_stream->instance_playback();
+ AudioServer::get_singleton()->unlock();
+
if (stream_playback.is_null()) {
stream.unref();
ERR_FAIL_COND(stream_playback.is_null());
}
- AudioServer::get_singleton()->unlock();
+
}
Ref<AudioStream> AudioStreamPlayer2D::get_stream() const {
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 3a99e917eb..5a0a9c6e6a 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -291,10 +291,10 @@ public:
RID get_canvas() const;
Ref<World2D> get_world_2d() const;
- void set_material(const Ref<Material> &p_material);
+ virtual void set_material(const Ref<Material> &p_material);
Ref<Material> get_material() const;
- void set_use_parent_material(bool p_use_parent_material);
+ virtual void set_use_parent_material(bool p_use_parent_material);
bool get_use_parent_material() const;
Ref<InputEvent> make_input_local(const Ref<InputEvent> &p_event) const;
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index ab8277ecf3..1bca2c6f37 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -435,7 +435,7 @@ void Light2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask");
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 66b0aa2299..f6bc943adb 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -48,6 +48,7 @@ public:
SHADOW_FILTER_NONE,
SHADOW_FILTER_PCF3,
SHADOW_FILTER_PCF5,
+ SHADOW_FILTER_PCF7,
SHADOW_FILTER_PCF9,
SHADOW_FILTER_PCF13,
};
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index 9eea5191b9..1235013af4 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -139,7 +139,7 @@ void LineBuilder::build() {
float current_distance0 = 0.f;
float current_distance1 = 0.f;
- float total_distance;
+ float total_distance = 0.f;
_interpolate_color = gradient != NULL;
bool distance_required = _interpolate_color || texture_mode == LINE_TEXTURE_TILE;
if (distance_required)
diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp
index fa488b6b23..74d835dfb2 100644
--- a/scene/2d/navigation2d.cpp
+++ b/scene/2d/navigation2d.cpp
@@ -476,7 +476,6 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
Polygon *left_poly = end_poly;
Polygon *right_poly = end_poly;
Polygon *p = end_poly;
- path.push_back(end_point);
while (p) {
@@ -534,7 +533,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
left_poly = p;
portal_left = apex_point;
portal_right = apex_point;
- if (path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON)
+ if (!path.size() || path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON)
path.push_back(apex_point);
skip = true;
//print_line("addpoint left");
@@ -555,7 +554,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
right_poly = p;
portal_right = apex_point;
portal_left = apex_point;
- if (path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON)
+ if (!path.size() || path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON)
path.push_back(apex_point);
//print_line("addpoint right");
//print_line("***CLIP RIGHT");
@@ -568,16 +567,10 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
p = NULL;
}
- if (path[path.size() - 1].distance_to(begin_point) > CMP_EPSILON)
- path.push_back(begin_point);
-
- path.invert();
-
} else {
//midpoints
Polygon *p = end_poly;
- path.push_back(end_point);
while (true) {
int prev = p->prev_edge;
int prev_n = (p->prev_edge + 1) % p->edges.size();
@@ -587,11 +580,20 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
if (p == begin_poly)
break;
}
+ }
- if (path[path.size() - 1].distance_to(begin_point) > CMP_EPSILON)
- path.push_back(begin_point);
+ if (!path.size() || path[path.size() - 1].distance_squared_to(begin_point) > CMP_EPSILON) {
+ path.push_back(begin_point); // Add the begin point
+ } else {
+ path[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point
+ }
+
+ path.invert();
- path.invert();
+ if (path.size() <= 1 || path[path.size() - 1].distance_squared_to(end_point) > CMP_EPSILON) {
+ path.push_back(end_point); // Add the end point
+ } else {
+ path[path.size() - 1] = end_point; // Replace last midpoint by the exact end point
}
return path;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 6ac946ea37..b1eb2ba267 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -883,7 +883,7 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody2D::get_colliding_bodies);
- BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state:Physics2DDirectBodyState")));
+ BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "Physics2DDirectBodyState")));
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index d41db1dce5..b1cc8c226a 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -336,6 +336,7 @@ void TileMap::_update_dirty_quadrants() {
if (mat.is_valid())
vs->canvas_item_set_material(canvas_item, mat->get_rid());
vs->canvas_item_set_parent(canvas_item, get_canvas_item());
+ _update_item_material_state(canvas_item);
Transform2D xform;
xform.set_origin(q.pos);
vs->canvas_item_set_transform(canvas_item, xform);
@@ -780,6 +781,35 @@ void TileMap::_clear_quadrants() {
}
}
+void TileMap::set_material(const Ref<Material> &p_material) {
+
+ CanvasItem::set_material(p_material);
+ _update_all_items_material_state();
+}
+
+void TileMap::set_use_parent_material(bool p_use_parent_material) {
+
+ CanvasItem::set_use_parent_material(p_use_parent_material);
+ _update_all_items_material_state();
+}
+
+void TileMap::_update_all_items_material_state() {
+
+ for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
+
+ Quadrant &q = E->get();
+ for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
+
+ _update_item_material_state(E->get());
+ }
+ }
+}
+
+void TileMap::_update_item_material_state(const RID &p_canvas_item) {
+
+ VS::get_singleton()->canvas_item_set_use_parent_material(p_canvas_item, get_use_parent_material() || get_material().is_valid());
+}
+
void TileMap::clear() {
_clear_quadrants();
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index f401d51eeb..c9d14e09d1 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -183,6 +183,9 @@ private:
void _update_quadrant_transform();
void _recompute_rect_cache();
+ void _update_all_items_material_state();
+ _FORCE_INLINE_ void _update_item_material_state(const RID &p_canvas_item);
+
_FORCE_INLINE_ int _get_quadrant_size() const;
void _set_tile_data(const PoolVector<int> &p_data);
@@ -278,6 +281,10 @@ public:
virtual void set_light_mask(int p_light_mask);
+ virtual void set_material(const Ref<Material> &p_material);
+
+ virtual void set_use_parent_material(bool p_use_parent_material);
+
void clear();
TileMap();
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp
index 545be8bc5f..caf313190b 100644
--- a/scene/3d/arvr_nodes.cpp
+++ b/scene/3d/arvr_nodes.cpp
@@ -264,7 +264,7 @@ void ARVRAnchor::_notification(int p_what) {
// our basis is scaled to the size of the plane the anchor is tracking
// extract the size from our basis and reset the scale
size = transform.basis.get_scale() * world_scale;
- transform.basis.set_scale(Vector3(1.0, 1.0, 1.0));
+ transform.basis.orthonormalize();
// apply our reference frame and set our transform
set_transform(arvr_server->get_reference_frame() * transform);
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 6efdf25f0d..a69bec2fc8 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -183,7 +183,7 @@ void AudioStreamPlayer3D::_mix_audio() {
float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
- float att;
+ float att = 0;
switch (attenuation_model) {
case ATTENUATION_INVERSE_DISTANCE: {
att = Math::linear2db(1.0 / ((p_distance / unit_size) + 000001));
@@ -196,6 +196,10 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
case ATTENUATION_LOGARITHMIC: {
att = -20 * Math::log(p_distance / unit_size + 000001);
} break;
+ default: {
+ ERR_PRINT("Unknown attenuation type");
+ break;
+ }
}
att += unit_db;
@@ -555,12 +559,12 @@ void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
stream = p_stream;
stream_playback = p_stream->instance_playback();
+ AudioServer::get_singleton()->unlock();
+
if (stream_playback.is_null()) {
stream.unref();
ERR_FAIL_COND(stream_playback.is_null());
}
-
- AudioServer::get_singleton()->unlock();
}
Ref<AudioStream> AudioStreamPlayer3D::get_stream() const {
diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp
index 4d4ed30d03..5f1151f8e9 100644
--- a/scene/3d/collision_shape.cpp
+++ b/scene/3d/collision_shape.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* body_shape.cpp */
+/* collision_shape.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/scene/3d/collision_shape.h b/scene/3d/collision_shape.h
index 6d849f42af..94621177cb 100644
--- a/scene/3d/collision_shape.h
+++ b/scene/3d/collision_shape.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* body_shape.h */
+/* collision_shape.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 0232ce7653..bb54a43028 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -548,8 +548,8 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons
//plot the face by guessing it's albedo and emission value
//find best axis to map to, for scanning values
- int closest_axis;
- float closest_dot;
+ int closest_axis = 0;
+ float closest_dot = 0;
Plane plane = Plane(p_vtx[0], p_vtx[1], p_vtx[2]);
Vector3 normal = plane.normal;
diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h
index b2bcb5af1a..6db825bf54 100644
--- a/scene/3d/immediate_geometry.h
+++ b/scene/3d/immediate_geometry.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* immediate_geometry.h */
+/* immediate_geometry.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 5b48ee4af8..09b253b309 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -334,6 +334,7 @@ void DirectionalLight::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE);
BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL);
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
@@ -343,9 +344,10 @@ void DirectionalLight::_bind_methods() {
DirectionalLight::DirectionalLight()
: Light(VisualServer::LIGHT_DIRECTIONAL) {
- set_param(PARAM_SHADOW_NORMAL_BIAS, 0.2);
- set_param(PARAM_SHADOW_BIAS, 1.0);
+ set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8);
+ set_param(PARAM_SHADOW_BIAS, 0.1);
set_param(PARAM_SHADOW_MAX_DISTANCE, 200);
+ set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25);
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
blend_splits = false;
diff --git a/scene/3d/light.h b/scene/3d/light.h
index 93dd4828da..5d589d33e5 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -58,6 +58,7 @@ public:
PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
PARAM_SHADOW_NORMAL_BIAS = VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS,
PARAM_SHADOW_BIAS = VS::LIGHT_PARAM_SHADOW_BIAS,
+ PARAM_SHADOW_BIAS_SPLIT_SCALE = VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
PARAM_MAX = VS::LIGHT_PARAM_MAX
};
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index b149dcd2dc..6a8226c0e1 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -842,7 +842,7 @@ void RigidBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody::get_colliding_bodies);
- BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state:PhysicsDirectBodyState")));
+ BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState")));
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
@@ -912,34 +912,24 @@ RigidBody::~RigidBody() {
//////////////////////////////////////////////////////
//////////////////////////
-Dictionary KinematicBody::_move(const Vector3 &p_motion) {
+Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion) {
Collision col;
- if (move(p_motion, col)) {
- Dictionary d;
- d["position"] = col.collision;
- d["normal"] = col.collision;
- d["local_shape"] = col.local_shape;
- d["travel"] = col.travel;
- d["remainder"] = col.remainder;
- d["collider_id"] = col.collider;
- if (col.collider) {
- d["collider"] = ObjectDB::get_instance(col.collider);
- } else {
- d["collider"] = Variant();
+ if (move_and_collide(p_motion, col)) {
+ if (motion_cache.is_null()) {
+ motion_cache.instance();
+ motion_cache->owner = this;
}
- d["collider_shape_index"] = col.collider_shape;
- d["collider_metadata"] = col.collider_metadata;
-
- return d;
+ motion_cache->collision = col;
- } else {
- return Dictionary();
+ return motion_cache;
}
+
+ return Ref<KinematicCollision>();
}
-bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) {
+bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_collision) {
Transform gt = get_global_transform();
PhysicsServer::MotionResult result;
@@ -963,7 +953,7 @@ bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) {
return colliding;
}
-Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) {
+Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
Vector3 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
Vector3 lv = p_linear_velocity;
@@ -974,11 +964,11 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
colliders.clear();
floor_velocity = Vector3();
- while (p_max_bounces) {
+ while (p_max_slides) {
Collision collision;
- bool collided = move(motion, collision);
+ bool collided = move_and_collide(motion, collision);
if (collided) {
@@ -1016,7 +1006,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
break;
}
- p_max_bounces--;
+ p_max_slides--;
if (motion == Vector3())
break;
}
@@ -1058,79 +1048,36 @@ float KinematicBody::get_safe_margin() const {
return margin;
}
-
-int KinematicBody::get_collision_count() const {
+int KinematicBody::get_slide_count() const {
return colliders.size();
}
-Vector3 KinematicBody::get_collision_position(int p_collision) const {
-
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].collision;
-}
-Vector3 KinematicBody::get_collision_normal(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].normal;
+KinematicBody::Collision KinematicBody::get_slide_collision(int p_bounce) const {
+ ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision());
+ return colliders[p_bounce];
}
-Vector3 KinematicBody::get_collision_travel(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].travel;
-}
-Vector3 KinematicBody::get_collision_remainder(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].remainder;
-}
-Object *KinematicBody::get_collision_local_shape(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
- uint32_t owner = shape_find_owner(colliders[p_collision].local_shape);
- return shape_owner_get_owner(owner);
-}
-Object *KinematicBody::get_collision_collider(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
+Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
- if (colliders[p_collision].collider) {
- return ObjectDB::get_instance(colliders[p_collision].collider);
+ ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision>());
+ if (p_bounce > slide_colliders.size()) {
+ slide_colliders.resize(p_bounce + 1);
}
- return NULL;
-}
-ObjectID KinematicBody::get_collision_collider_id(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0);
-
- return colliders[p_collision].collider;
-}
-Object *KinematicBody::get_collision_collider_shape(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
- Object *collider = get_collision_collider(p_collision);
- if (collider) {
- CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider);
- if (obj2d) {
- uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape);
- return obj2d->shape_owner_get_owner(owner);
- }
+ if (slide_colliders[p_bounce].is_null()) {
+ slide_colliders[p_bounce].instance();
+ slide_colliders[p_bounce]->owner = this;
}
- return NULL;
-}
-int KinematicBody::get_collision_collider_shape_index(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1);
- return colliders[p_collision].collider_shape;
-}
-Vector3 KinematicBody::get_collision_collider_velocity(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].collider_vel;
-}
-Variant KinematicBody::get_collision_collider_metadata(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant());
- return colliders[p_collision].collider_metadata;
+ slide_colliders[p_bounce]->collision = colliders[p_bounce];
+ return slide_colliders[p_bounce];
}
void KinematicBody::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody::_move);
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody::_move);
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_slides", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody::test_move);
@@ -1142,18 +1089,8 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin);
- ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody::get_collision_count);
- ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody::get_collision_position);
- ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody::get_collision_normal);
- ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody::get_collision_travel);
- ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody::get_collision_remainder);
- ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody::get_collision_local_shape);
- ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody::get_collision_collider);
- ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody::get_collision_collider_id);
- ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody::get_collision_collider_shape);
- ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody::get_collision_collider_shape_index);
- ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody::get_collision_collider_velocity);
- ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody::get_collision_collider_metadata);
+ ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count);
+ ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
@@ -1168,4 +1105,106 @@ KinematicBody::KinematicBody()
on_wall = false;
}
KinematicBody::~KinematicBody() {
+
+ if (motion_cache.is_valid()) {
+ motion_cache->owner = NULL;
+ }
+
+ for (int i = 0; i < slide_colliders.size(); i++) {
+ if (slide_colliders[i].is_valid()) {
+ slide_colliders[i]->owner = NULL;
+ }
+ }
+}
+///////////////////////////////////////
+
+Vector3 KinematicCollision::get_position() const {
+
+ return collision.collision;
+}
+Vector3 KinematicCollision::get_normal() const {
+ return collision.normal;
+}
+Vector3 KinematicCollision::get_travel() const {
+ return collision.travel;
+}
+Vector3 KinematicCollision::get_remainder() const {
+ return collision.remainder;
+}
+Object *KinematicCollision::get_local_shape() const {
+ ERR_FAIL_COND_V(!owner, NULL);
+ uint32_t ownerid = owner->shape_find_owner(collision.local_shape);
+ return owner->shape_owner_get_owner(ownerid);
+}
+
+Object *KinematicCollision::get_collider() const {
+
+ if (collision.collider) {
+ return ObjectDB::get_instance(collision.collider);
+ }
+
+ return NULL;
+}
+ObjectID KinematicCollision::get_collider_id() const {
+
+ return collision.collider;
+}
+Object *KinematicCollision::get_collider_shape() const {
+
+ Object *collider = get_collider();
+ if (collider) {
+ CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider);
+ if (obj2d) {
+ uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape);
+ return obj2d->shape_owner_get_owner(ownerid);
+ }
+ }
+
+ return NULL;
+}
+int KinematicCollision::get_collider_shape_index() const {
+
+ return collision.collider_shape;
+}
+Vector3 KinematicCollision::get_collider_velocity() const {
+
+ return collision.collider_vel;
+}
+Variant KinematicCollision::get_collider_metadata() const {
+
+ return Variant();
+}
+
+void KinematicCollision::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision::get_position);
+ ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision::get_normal);
+ ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision::get_travel);
+ ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision::get_remainder);
+ ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision::get_local_shape);
+ ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision::get_collider);
+ ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision::get_collider_id);
+ ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision::get_collider_shape);
+ ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision::get_collider_shape_index);
+ ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision::get_collider_velocity);
+ ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision::get_collider_metadata);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "normal"), "", "get_normal");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_collider_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata");
+}
+
+KinematicCollision::KinematicCollision() {
+ collision.collider = 0;
+ collision.collider_shape = 0;
+ collision.local_shape = 0;
+ owner = NULL;
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 23d752ad76..f88b3860dc 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -261,6 +261,8 @@ public:
VARIANT_ENUM_CAST(RigidBody::Mode);
VARIANT_ENUM_CAST(RigidBody::AxisLock);
+class KinematicCollision;
+
class KinematicBody : public PhysicsBody {
GDCLASS(KinematicBody, PhysicsBody);
@@ -286,42 +288,62 @@ private:
bool on_ceiling;
bool on_wall;
Vector<Collision> colliders;
+ Vector<Ref<KinematicCollision> > slide_colliders;
+ Ref<KinematicCollision> motion_cache;
_FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
- Dictionary _move(const Vector3 &p_motion);
+ Ref<KinematicCollision> _move(const Vector3 &p_motion);
+ Ref<KinematicCollision> _get_slide_collision(int p_bounce);
protected:
static void _bind_methods();
public:
- bool move(const Vector3 &p_motion, Collision &r_collision);
+ bool move_and_collide(const Vector3 &p_motion, Collision &r_collision);
bool test_move(const Transform &p_from, const Vector3 &p_motion);
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45));
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
Vector3 get_floor_velocity() const;
- int get_collision_count() const;
- Vector3 get_collision_position(int p_collision) const;
- Vector3 get_collision_normal(int p_collision) const;
- Vector3 get_collision_travel(int p_collision) const;
- Vector3 get_collision_remainder(int p_collision) const;
- Object *get_collision_local_shape(int p_collision) const;
- Object *get_collision_collider(int p_collision) const;
- ObjectID get_collision_collider_id(int p_collision) const;
- Object *get_collision_collider_shape(int p_collision) const;
- int get_collision_collider_shape_index(int p_collision) const;
- Vector3 get_collision_collider_velocity(int p_collision) const;
- Variant get_collision_collider_metadata(int p_collision) const;
+ int get_slide_count() const;
+ Collision get_slide_collision(int p_bounce) const;
KinematicBody();
~KinematicBody();
};
+class KinematicCollision : public Reference {
+
+ GDCLASS(KinematicCollision, Reference);
+
+ KinematicBody *owner;
+ friend class KinematicBody;
+ KinematicBody::Collision collision;
+
+protected:
+ static void _bind_methods();
+
+public:
+ Vector3 get_position() const;
+ Vector3 get_normal() const;
+ Vector3 get_travel() const;
+ Vector3 get_remainder() const;
+ Object *get_local_shape() const;
+ Object *get_collider() const;
+ ObjectID get_collider_id() const;
+ Object *get_collider_shape() const;
+ int get_collider_shape_index() const;
+ Vector3 get_collider_velocity() const;
+ Variant get_collider_metadata() const;
+
+ KinematicCollision();
+};
+
#endif // PHYSICS_BODY__H
diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp
index 3d402fa5af..8faf985b11 100644
--- a/scene/3d/remote_transform.cpp
+++ b/scene/3d/remote_transform.cpp
@@ -1,6 +1,5 @@
-
/*************************************************************************/
-/* remote_transform.cpp */
+/* remote_transform.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h
index 71d7277118..609430340b 100644
--- a/scene/animation/animation_tree_player.h
+++ b/scene/animation/animation_tree_player.h
@@ -347,7 +347,7 @@ public:
void animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation);
String animation_node_get_master_animation(const StringName &p_node) const;
- void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable);
+ void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter);
void animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const;
bool animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const;
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 3cd953773f..fb61c43d5c 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -560,12 +560,16 @@ void Tween::_tween_process(float p_delta) {
switch (data.type) {
case INTER_PROPERTY:
- case INTER_METHOD:
- break;
+ case INTER_METHOD: {
+ Variant result = _run_equation(data);
+ emit_signal("tween_step", object, data.key, data.elapsed, result);
+ _apply_tween_value(data, result);
+ if (data.finish)
+ _apply_tween_value(data, data.final_val);
+ } break;
+
case INTER_CALLBACK:
if (data.finish) {
-
- Variant::CallError error;
if (data.call_deferred) {
switch (data.args) {
@@ -588,8 +592,8 @@ void Tween::_tween_process(float p_delta) {
object->call_deferred(data.key, data.arg[0], data.arg[1], data.arg[2], data.arg[3], data.arg[4]);
break;
}
-
} else {
+ Variant::CallError error;
Variant *arg[5] = {
&data.arg[0],
&data.arg[1],
@@ -599,19 +603,11 @@ void Tween::_tween_process(float p_delta) {
};
object->call(data.key, (const Variant **)arg, data.args, error);
}
- if (!repeat)
- call_deferred("_remove", object, data.key, true);
}
- continue;
+ break;
}
- Variant result = _run_equation(data);
- emit_signal("tween_step", object, data.key, data.elapsed, result);
-
- _apply_tween_value(data, result);
-
if (data.finish) {
- _apply_tween_value(data, data.final_val);
emit_signal("tween_completed", object, data.key);
// not repeat mode, remove completed action
if (!repeat)
diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp
index 5d71f702df..8bd924e7ce 100644
--- a/scene/audio/audio_player.cpp
+++ b/scene/audio/audio_player.cpp
@@ -139,12 +139,12 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
stream = p_stream;
stream_playback = p_stream->instance_playback();
+ AudioServer::get_singleton()->unlock();
+
if (stream_playback.is_null()) {
stream.unref();
ERR_FAIL_COND(stream_playback.is_null());
}
-
- AudioServer::get_singleton()->unlock();
}
Ref<AudioStream> AudioStreamPlayer::get_stream() const {
diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h
index 4a1adb5f2f..4da06be8d1 100644
--- a/scene/gui/check_box.h
+++ b/scene/gui/check_box.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* check_box.h */
+/* check_box.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index e2da5e4981..961fccc804 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2703,7 +2703,7 @@ void Control::_bind_methods() {
ADD_SIGNAL(MethodInfo("minimum_size_changed"));
ADD_SIGNAL(MethodInfo("modal_closed"));
- BIND_VMETHOD(MethodInfo("has_point:bool", PropertyInfo(Variant::VECTOR2, "point")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_point", PropertyInfo(Variant::VECTOR2, "point")));
}
Control::Control() {
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 8730be0c06..bef0808fd0 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -270,7 +270,7 @@ void GraphNode::_notification(int p_what) {
}
}
- if (resizeable) {
+ if (resizable) {
draw_texture(resizer, get_size() - resizer->get_size());
}
}
@@ -594,7 +594,7 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<Texture> resizer = get_icon("resizer");
- if (resizeable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) {
+ if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) {
resizing = true;
resizing_from = mpos;
@@ -645,15 +645,15 @@ bool GraphNode::is_comment() const {
return comment;
}
-void GraphNode::set_resizeable(bool p_enable) {
+void GraphNode::set_resizable(bool p_enable) {
- resizeable = p_enable;
+ resizable = p_enable;
update();
}
-bool GraphNode::is_resizeable() const {
+bool GraphNode::is_resizable() const {
- return resizeable;
+ return resizable;
}
void GraphNode::_bind_methods() {
@@ -678,8 +678,8 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_comment", "comment"), &GraphNode::set_comment);
ClassDB::bind_method(D_METHOD("is_comment"), &GraphNode::is_comment);
- ClassDB::bind_method(D_METHOD("set_resizeable", "resizeable"), &GraphNode::set_resizeable);
- ClassDB::bind_method(D_METHOD("is_resizeable"), &GraphNode::is_resizeable);
+ ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &GraphNode::set_resizable);
+ ClassDB::bind_method(D_METHOD("is_resizable"), &GraphNode::is_resizable);
ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphNode::set_selected);
ClassDB::bind_method(D_METHOD("is_selected"), &GraphNode::is_selected);
@@ -702,7 +702,7 @@ void GraphNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizeable"), "set_resizeable", "is_resizeable");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable");
ADD_SIGNAL(MethodInfo("offset_changed"));
ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to")));
@@ -722,7 +722,7 @@ GraphNode::GraphNode() {
connpos_dirty = true;
set_mouse_filter(MOUSE_FILTER_STOP);
comment = false;
- resizeable = false;
+ resizable = false;
resizing = false;
selected = false;
}
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index 416d711aab..a606e47acd 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -68,7 +68,7 @@ private:
bool show_close;
Vector2 offset;
bool comment;
- bool resizeable;
+ bool resizable;
bool resizing;
Vector2 resizing_from;
@@ -151,8 +151,8 @@ public:
void set_comment(bool p_enable);
bool is_comment() const;
- void set_resizeable(bool p_enable);
- bool is_resizeable() const;
+ void set_resizable(bool p_enable);
+ bool is_resizable() const;
virtual Size2 get_minimum_size() const;
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 9bad871ef9..9a605c98f3 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -151,6 +151,20 @@ Color ItemList::get_item_custom_bg_color(int p_idx) const {
return items[p_idx].custom_bg;
}
+void ItemList::set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color) {
+
+ ERR_FAIL_INDEX(p_idx, items.size());
+
+ items[p_idx].custom_fg = p_custom_fg_color;
+}
+
+Color ItemList::get_item_custom_fg_color(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx, items.size(), Color());
+
+ return items[p_idx].custom_fg;
+}
+
void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
@@ -534,7 +548,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
- if (diff < int(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
+ if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
for (int i = current - 1; i >= 0; i--) {
@@ -569,7 +583,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
- if (diff < int(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
+ if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
for (int i = current + 1; i < items.size(); i++) {
@@ -1021,7 +1035,7 @@ void ItemList::_notification(int p_what) {
else
max_len = size.x;
- Color modulate = items[i].selected ? font_color_selected : font_color;
+ Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color);
if (items[i].disabled)
modulate.a *= 0.5;
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index 8166975408..673b7d8956 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -61,6 +61,7 @@ private:
bool tooltip_enabled;
Variant metadata;
String tooltip;
+ Color custom_fg;
Color custom_bg;
Rect2 rect_cache;
@@ -150,6 +151,9 @@ public:
void set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_color);
Color get_item_custom_bg_color(int p_idx) const;
+ void set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color);
+ Color get_item_custom_fg_color(int p_idx) const;
+
void select(int p_idx, bool p_single = true);
void unselect(int p_idx);
bool is_selected(int p_idx) const;
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 5fe3dd0129..e1f77594da 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -85,7 +85,7 @@ void Label::_notification(int p_what) {
Size2 string_size;
Size2 size = get_size();
-
+ Ref<StyleBox> style = get_stylebox("normal");
Ref<Font> font = get_font("font");
Color font_color = get_color("font_color");
Color font_color_shadow = get_color("font_color_shadow");
@@ -93,6 +93,8 @@ void Label::_notification(int p_what) {
Point2 shadow_ofs(get_constant("shadow_offset_x"), get_constant("shadow_offset_y"));
int line_spacing = get_constant("line_spacing");
+ style->draw(ci, Rect2(Point2(0, 0), get_size()));
+
VisualServer::get_singleton()->canvas_item_set_distance_field_mode(get_canvas_item(), font.is_valid() && font->is_distance_field_hint());
int font_h = font->get_height() + line_spacing;
@@ -193,21 +195,20 @@ void Label::_notification(int p_what) {
case ALIGN_FILL:
case ALIGN_LEFT: {
- x_ofs = 0;
+ x_ofs = style->get_offset().x;
} break;
case ALIGN_CENTER: {
x_ofs = int(size.width - (taken + spaces * space_w)) / 2;
-
} break;
case ALIGN_RIGHT: {
- x_ofs = int(size.width - (taken + spaces * space_w));
-
+ x_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (taken + spaces * space_w));
} break;
}
- int y_ofs = (line - lines_skipped) * font_h + font->get_ascent();
+ int y_ofs = style->get_offset().y;
+ y_ofs += (line - lines_skipped) * font_h + font->get_ascent();
y_ofs += vbegin + line * vsep;
while (from != to) {
@@ -288,8 +289,10 @@ void Label::_notification(int p_what) {
Size2 Label::get_minimum_size() const {
+ Size2 min_style = get_stylebox("normal")->get_minimum_size();
+
if (autowrap)
- return Size2(1, clip ? 1 : minsize.height);
+ return Size2(1, clip ? 1 : minsize.height) + min_style;
else {
// don't want to mutable everything
@@ -299,7 +302,7 @@ Size2 Label::get_minimum_size() const {
Size2 ms = minsize;
if (clip)
ms.width = 1;
- return ms;
+ return ms + min_style;
}
}
@@ -350,7 +353,7 @@ int Label::get_visible_line_count() const {
int line_spacing = get_constant("line_spacing");
int font_h = get_font("font")->get_height() + line_spacing;
- int lines_visible = (get_size().y + line_spacing) / font_h;
+ int lines_visible = (get_size().height - get_stylebox("normal")->get_minimum_size().height + line_spacing) / font_h;
if (lines_visible > line_count)
lines_visible = line_count;
@@ -370,7 +373,8 @@ void Label::regenerate_word_cache() {
memdelete(current);
}
- int width = autowrap ? get_size().width : get_longest_line_width();
+ Ref<StyleBox> style = get_stylebox("normal");
+ int width = autowrap ? (get_size().width - style->get_minimum_size().width) : get_longest_line_width();
Ref<Font> font = get_font("font");
int current_word_size = 0;
@@ -397,7 +401,7 @@ void Label::regenerate_word_cache() {
bool separatable = (current >= 0x2E08 && current <= 0xFAFF) || (current >= 0xFE30 && current <= 0xFE4F);
//current>=33 && (current < 65||current >90) && (current<97||current>122) && (current<48||current>57);
bool insert_newline = false;
- int char_width;
+ int char_width = 0;
if (current < 33) {
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 66b4e6cec1..6a5f56c78c 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -631,7 +631,7 @@ void LineEdit::_notification(int p_what) {
if (has_icon("right_icon")) {
Ref<Texture> r_icon = Control::get_icon("right_icon");
ofs_max -= r_icon->get_width();
- r_icon->draw(ci, Point2(width - r_icon->get_width() - x_ofs, y_ofs), Color(1, 1, 1, disabled_alpha * .9));
+ r_icon->draw(ci, Point2(width - r_icon->get_width() - x_ofs, height / 2 - r_icon->get_height() / 2), Color(1, 1, 1, disabled_alpha * .9));
}
int caret_height = font->get_height() > y_area ? y_area : font->get_height();
diff --git a/scene/gui/patch_9_rect.cpp b/scene/gui/patch_9_rect.cpp
index 6b2deeb209..92c34dd3f9 100644
--- a/scene/gui/patch_9_rect.cpp
+++ b/scene/gui/patch_9_rect.cpp
@@ -61,7 +61,7 @@ void NinePatchRect::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &NinePatchRect::set_region_rect);
ClassDB::bind_method(D_METHOD("get_region_rect"), &NinePatchRect::get_region_rect);
ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &NinePatchRect::set_draw_center);
- ClassDB::bind_method(D_METHOD("get_draw_center"), &NinePatchRect::get_draw_center);
+ ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &NinePatchRect::is_draw_center_enabled);
ClassDB::bind_method(D_METHOD("set_h_axis_stretch_mode", "mode"), &NinePatchRect::set_h_axis_stretch_mode);
ClassDB::bind_method(D_METHOD("get_h_axis_stretch_mode"), &NinePatchRect::get_h_axis_stretch_mode);
ClassDB::bind_method(D_METHOD("set_v_axis_stretch_mode", "mode"), &NinePatchRect::set_v_axis_stretch_mode);
@@ -70,7 +70,7 @@ void NinePatchRect::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "get_draw_center");
+ ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled");
ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_GROUP("Patch Margin", "patch_margin_");
@@ -151,13 +151,13 @@ Rect2 NinePatchRect::get_region_rect() const {
return region_rect;
}
-void NinePatchRect::set_draw_center(bool p_draw) {
+void NinePatchRect::set_draw_center(bool p_enabled) {
- draw_center = p_draw;
+ draw_center = p_enabled;
update();
}
-bool NinePatchRect::get_draw_center() const {
+bool NinePatchRect::is_draw_center_enabled() const {
return draw_center;
}
diff --git a/scene/gui/patch_9_rect.h b/scene/gui/patch_9_rect.h
index 4cf93e4c05..808b7a1f5d 100644
--- a/scene/gui/patch_9_rect.h
+++ b/scene/gui/patch_9_rect.h
@@ -67,8 +67,8 @@ public:
void set_region_rect(const Rect2 &p_region_rect);
Rect2 get_region_rect() const;
- void set_draw_center(bool p_draw);
- bool get_draw_center() const;
+ void set_draw_center(bool p_enabled);
+ bool is_draw_center_enabled() const;
void set_h_axis_stretch_mode(AxisStretchMode p_mode);
AxisStretchMode get_h_axis_stretch_mode() const;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index a3f116c883..e51955ed66 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -80,6 +80,10 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
return NULL;
}
+Rect2 RichTextLabel::_get_text_rect() {
+ Ref<StyleBox> style = get_stylebox("normal");
+ return Rect2(style->get_offset(), get_size() - style->get_minimum_size());
+}
void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) {
RID ci;
@@ -583,7 +587,7 @@ void RichTextLabel::_update_scroll() {
int total_height = 0;
if (main->lines.size())
- total_height = main->lines[main->lines.size() - 1].height_accum_cache;
+ total_height = main->lines[main->lines.size() - 1].height_accum_cache + get_stylebox("normal")->get_minimum_size().height;
bool exceeds = total_height > get_size().height && scroll_active;
@@ -641,7 +645,11 @@ void RichTextLabel::_notification(int p_what) {
_update_scroll();
RID ci = get_canvas_item();
+
Size2 size = get_size();
+ Rect2 text_rect = _get_text_rect();
+
+ draw_style_box(get_stylebox("normal"), Rect2(Point2(), size));
if (has_focus()) {
VisualServer::get_singleton()->canvas_item_add_clip_ignore(ci, true);
@@ -657,10 +665,10 @@ void RichTextLabel::_notification(int p_what) {
int total_chars = 0;
while (from_line < main->lines.size()) {
- if (main->lines[from_line].height_accum_cache >= ofs)
+ if (main->lines[from_line].height_accum_cache + _get_text_rect().get_position().y >= ofs)
break;
- from_line++;
total_chars += main->lines[from_line].char_count;
+ from_line++;
}
if (from_line >= main->lines.size())
@@ -672,7 +680,7 @@ void RichTextLabel::_notification(int p_what) {
while (y < size.height && from_line < main->lines.size()) {
- _process_line(main, Point2(), y, size.width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars);
+ _process_line(main, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars);
total_chars += main->lines[from_line].char_count;
from_line++;
}
@@ -686,7 +694,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
*r_click_item = NULL;
Size2 size = get_size();
-
+ Rect2 text_rect = _get_text_rect();
int ofs = vscroll->get_value();
//todo, change to binary search
@@ -706,9 +714,9 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
Ref<Font> base_font = get_font("normal_font");
Color base_color = get_color("default_color");
- while (y < size.height && from_line < p_frame->lines.size()) {
+ while (y < text_rect.get_size().height && from_line < p_frame->lines.size()) {
- _process_line(p_frame, Point2(), y, size.width - scroll_w, from_line, PROCESS_POINTER, base_font, base_color, p_click, r_click_item, r_click_char, r_outside);
+ _process_line(p_frame, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_POINTER, base_font, base_color, p_click, r_click_item, r_click_char, r_outside);
if (r_click_item && *r_click_item)
return;
from_line++;
@@ -1015,13 +1023,14 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
//validate invalid lines!s
Size2 size = get_size();
+ Rect2 text_rect = _get_text_rect();
Ref<Font> base_font = get_font("normal_font");
for (int i = p_frame->first_invalid_line; i < p_frame->lines.size(); i++) {
int y = 0;
- _process_line(p_frame, Point2(), y, size.width - scroll_w, i, PROCESS_CACHE, base_font, Color());
+ _process_line(p_frame, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, i, PROCESS_CACHE, base_font, Color());
p_frame->lines[i].height_cache = y;
p_frame->lines[i].height_accum_cache = y;
@@ -1031,7 +1040,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
int total_height = 0;
if (p_frame->lines.size())
- total_height = p_frame->lines[p_frame->lines.size() - 1].height_accum_cache;
+ total_height = p_frame->lines[p_frame->lines.size() - 1].height_accum_cache + get_stylebox("normal")->get_minimum_size().height;
main->first_invalid_line = p_frame->lines.size();
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 74bf180b5d..4db2c3a8e9 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -276,6 +276,8 @@ private:
void _gui_input(Ref<InputEvent> p_event);
Item *_get_next_item(Item *p_item, bool p_free = false);
+ Rect2 _get_text_rect();
+
bool use_bbcode;
String bbcode;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 7a9daea73e..1738e303aa 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -430,7 +430,7 @@ void TextEdit::_notification(int p_what) {
double dist = sqrt(target_y * target_y);
double vel = ((target_y / dist) * v_scroll_speed) * get_fixed_process_delta_time();
- if (vel >= dist) {
+ if (Math::abs(vel) >= dist) {
v_scroll->set_value(target_v_scroll);
scrolling = false;
set_fixed_process(false);
@@ -2113,15 +2113,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
//keep indentation
int space_count = 0;
- for (int i = 0; i < text[cursor.line].length(); i++) {
- if (text[cursor.line][i] == '\t' && cursor.column > 0) {
+ for (int i = 0; i < cursor.column; i++) {
+ if (text[cursor.line][i] == '\t') {
if (indent_using_spaces) {
ins += space_indent;
} else {
ins += "\t";
}
space_count = 0;
- } else if (text[cursor.line][i] == ' ' && cursor.column > 0) {
+ } else if (text[cursor.line][i] == ' ') {
space_count++;
if (space_count == indent_size) {
@@ -2136,15 +2136,25 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
}
- if (auto_indent) {
- // indent once again if previous line will end with ':'
- // (i.e. colon precedes current cursor position)
- if (cursor.column > 0 && text[cursor.line][cursor.column - 1] == ':') {
+
+ bool brace_indent = false;
+
+ // no need to indent if we are going upwards.
+ if (auto_indent && !(k->get_command() && k->get_shift())) {
+ // indent once again if previous line will end with ':' or '{'
+ // (i.e. colon/brace precedes current cursor position)
+ if (cursor.column > 0 && (text[cursor.line][cursor.column - 1] == ':' || text[cursor.line][cursor.column - 1] == '{')) {
if (indent_using_spaces) {
ins += space_indent;
} else {
ins += "\t";
}
+
+ // no need to move the brace below if we are not taking the text with us.
+ if (text[cursor.line][cursor.column] == '}' && !k->get_command()) {
+ brace_indent = true;
+ ins += "\n" + ins.substr(1, ins.length() - 2);
+ }
}
}
@@ -2168,6 +2178,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (first_line) {
cursor_set_line(0);
+ } else if (brace_indent) {
+ cursor_set_line(cursor.line - 1);
+ cursor_set_column(text[cursor.line].length());
}
} break;
@@ -4531,7 +4544,7 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
bool inside_quotes = false;
- int qbegin, qend;
+ int qbegin = 0, qend = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == '"') {
if (inside_quotes) {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 5e15bceb7d..de17416d8e 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1116,7 +1116,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
cache.selected->draw(ci, r);
}
if (text_editor->is_visible_in_tree()) {
- text_editor->set_position(get_global_position() + r.position);
+ Vector2 ofs(0, (text_editor->get_size().height - r.size.height) / 2);
+ text_editor->set_position(get_global_position() + r.position - ofs);
}
}
@@ -2572,7 +2573,8 @@ bool Tree::edit_selected() {
} else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE || c.mode == TreeItem::CELL_MODE_RANGE_EXPRESSION) {
- Point2i textedpos = get_global_position() + rect.position;
+ Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2);
+ Point2i textedpos = get_global_position() + rect.position - ofs;
text_editor->set_position(textedpos);
text_editor->set_size(rect.size);
text_editor->clear();
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 1fb1eb2792..06d6d3ad5a 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -54,7 +54,7 @@ public:
CELL_MODE_CHECK, ///< string + check
CELL_MODE_RANGE, ///< Contains a range
CELL_MODE_RANGE_EXPRESSION, ///< Contains a range
- CELL_MODE_ICON, ///< Contains a icon, not editable
+ CELL_MODE_ICON, ///< Contains an icon, not editable
CELL_MODE_CUSTOM, ///< Contains a custom value, show a string, and an edit button
};
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 65aeb23609..a71b491bae 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* scene_main_loop.cpp */
+/* scene_tree.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -542,6 +542,10 @@ bool SceneTree::idle(float p_time) {
if (env_path != String()) {
fallback = ResourceLoader::load(env_path);
+ if (fallback.is_null()) {
+ //could not load fallback, set as empty
+ ProjectSettings::get_singleton()->set("rendering/environment/default_environment", "");
+ }
} else {
fallback.unref();
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 594b806cef..c116bec4fc 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* scene_main_loop.h */
+/* scene_tree.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 02da926e50..c71a280755 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -491,7 +491,7 @@ void Viewport::_notification(int p_what) {
if (physics_object_picking && (to_screen_rect == Rect2() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) {
Vector2 last_pos(1e20, 1e20);
- CollisionObject *last_object;
+ CollisionObject *last_object = NULL;
ObjectID last_id = 0;
PhysicsDirectSpaceState::RayResult result;
Physics2DDirectSpaceState *ss2d = Physics2DServer::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
@@ -604,7 +604,7 @@ void Viewport::_notification(int p_what) {
} else if (pos == last_pos) {
if (last_id) {
- if (ObjectDB::get_instance(last_id)) {
+ if (ObjectDB::get_instance(last_id) && last_object) {
//good, exists
last_object->_input_event(camera, ev, result.position, result.normal, result.shape);
if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
@@ -1202,15 +1202,15 @@ bool Viewport::get_vflip() const {
return vflip;
}
-void Viewport::set_clear_on_new_frame(bool p_enable) {
+void Viewport::set_clear_mode(ClearMode p_mode) {
- clear_on_new_frame = p_enable;
- //VisualServer::get_singleton()->viewport_set_clear_on_new_frame(viewport,p_enable);
+ clear_mode = p_mode;
+ VS::get_singleton()->viewport_set_clear_mode(viewport, VS::ViewportClearMode(p_mode));
}
-bool Viewport::get_clear_on_new_frame() const {
+Viewport::ClearMode Viewport::get_clear_mode() const {
- return clear_on_new_frame;
+ return clear_mode;
}
void Viewport::set_shadow_atlas_size(int p_size) {
@@ -1246,12 +1246,6 @@ Viewport::ShadowAtlasQuadrantSubdiv Viewport::get_shadow_atlas_quadrant_subdiv(i
return shadow_atlas_quadrant_subdiv[p_quadrant];
}
-void Viewport::clear() {
-
- //clear=true;
- //VisualServer::get_singleton()->viewport_clear(viewport);
-}
-
Transform2D Viewport::_get_input_pre_xform() const {
Transform2D pre_xf;
@@ -2625,10 +2619,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_vflip", "enable"), &Viewport::set_vflip);
ClassDB::bind_method(D_METHOD("get_vflip"), &Viewport::get_vflip);
- ClassDB::bind_method(D_METHOD("set_clear_on_new_frame", "enable"), &Viewport::set_clear_on_new_frame);
- ClassDB::bind_method(D_METHOD("get_clear_on_new_frame"), &Viewport::get_clear_on_new_frame);
+ ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &Viewport::set_clear_mode);
+ ClassDB::bind_method(D_METHOD("get_clear_mode"), &Viewport::get_clear_mode);
- ClassDB::bind_method(D_METHOD("clear"), &Viewport::clear);
ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &Viewport::set_update_mode);
ClassDB::bind_method(D_METHOD("get_update_mode"), &Viewport::get_update_mode);
@@ -2705,7 +2698,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Render Target", "render_target_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_on_new_frame"), "set_clear_on_new_frame", "get_clear_on_new_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,NextFrame"), "set_clear_mode", "get_clear_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode");
ADD_GROUP("Audio Listener", "audio_listener_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d");
@@ -2784,7 +2777,7 @@ Viewport::Viewport() {
gen_mipmaps = false;
vflip = false;
- clear_on_new_frame = true;
+
//clear=true;
update_mode = UPDATE_WHEN_VISIBLE;
@@ -2828,6 +2821,7 @@ Viewport::Viewport() {
usage = USAGE_3D;
debug_draw = DEBUG_DRAW_DISABLED;
+ clear_mode = CLEAR_MODE_ALWAYS;
}
Viewport::~Viewport() {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index f527fa4f5b..ce2bc991f5 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -140,6 +140,13 @@ public:
DEBUG_DRAW_WIREFRAME,
};
+ enum ClearMode {
+
+ CLEAR_MODE_ALWAYS,
+ CLEAR_MODE_NEVER,
+ CLEAR_MODE_ONLY_NEXT_FRAME
+ };
+
private:
friend class ViewportTexture;
@@ -182,7 +189,7 @@ private:
bool transparent_bg;
bool vflip;
- bool clear_on_new_frame;
+ ClearMode clear_mode;
bool filter;
bool gen_mipmaps;
@@ -395,9 +402,8 @@ public:
void set_vflip(bool p_enable);
bool get_vflip() const;
- void set_clear_on_new_frame(bool p_enable);
- bool get_clear_on_new_frame() const;
- void clear();
+ void set_clear_mode(ClearMode p_mode);
+ ClearMode get_clear_mode() const;
void set_update_mode(UpdateMode p_mode);
UpdateMode get_update_mode() const;
@@ -466,6 +472,7 @@ VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
VARIANT_ENUM_CAST(Viewport::Usage);
VARIANT_ENUM_CAST(Viewport::DebugDraw);
+VARIANT_ENUM_CAST(Viewport::ClearMode);
VARIANT_ENUM_CAST(Viewport::RenderInfo);
#endif
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index e01f5e3cdf..69c17f4912 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -378,6 +378,7 @@ void register_scene_types() {
ClassDB::register_virtual_class<CollisionObject>();
ClassDB::register_class<StaticBody>();
ClassDB::register_class<RigidBody>();
+ ClassDB::register_class<KinematicCollision>();
ClassDB::register_class<KinematicBody>();
ClassDB::register_class<VehicleBody>();
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 1a2c8333ef..eae95d9247 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -970,7 +970,12 @@ int Animation::_find(const Vector<K> &p_keys, float p_time) const {
int low = 0;
int high = len - 1;
- int middle;
+ int middle = 0;
+
+#if DEBUG_ENABLED
+ if (low > high)
+ ERR_PRINT("low > high, this may be a bug");
+#endif
const K *keys = &p_keys[0];
@@ -1289,7 +1294,7 @@ Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3
TransformTrack *tt = static_cast<TransformTrack *>(t);
- bool ok;
+ bool ok = false;
TransformKey tk = _interpolate(tt->transforms, p_time, tt->interpolation, tt->loop_wrap, &ok);
@@ -1315,7 +1320,7 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
ERR_FAIL_COND_V(t->type != TYPE_VALUE, Variant());
ValueTrack *vt = static_cast<ValueTrack *>(t);
- bool ok;
+ bool ok = false;
Variant res = _interpolate(vt->values, p_time, vt->update_mode == UPDATE_CONTINUOUS ? vt->interpolation : INTERPOLATION_NEAREST, vt->loop_wrap, &ok);
diff --git a/scene/resources/color_ramp.h b/scene/resources/color_ramp.h
index 816152d51f..316c188d59 100644
--- a/scene/resources/color_ramp.h
+++ b/scene/resources/color_ramp.h
@@ -88,7 +88,12 @@ public:
//binary search
int low = 0;
int high = points.size() - 1;
- int middle;
+ int middle = 0;
+
+#if DEBUG_ENABLED
+ if (low > high)
+ ERR_PRINT("low > high, this may be a bug");
+#endif
while (low <= high) {
middle = (low + high) / 2;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 08de33175a..fdea5960e5 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -408,6 +408,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// Label
+ theme->set_stylebox("normal", "Label", memnew(StyleBoxEmpty));
theme->set_font("font", "Label", default_font);
theme->set_color("font_color", "Label", Color(1, 1, 1));
@@ -525,7 +526,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
theme->set_stylebox("grabber_highlight", "VSlider", make_stylebox(vslider_grabber_hl_png, 6, 6, 6, 6));
theme->set_stylebox("grabber_disabled", "VSlider", make_stylebox(vslider_grabber_disabled_png, 6, 6, 6, 6));
- theme->set_stylebox("focus", "HSlider", focus);
+ theme->set_stylebox("focus", "VSlider", focus);
theme->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png));
theme->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png));
@@ -793,6 +794,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// RichTextLabel
theme->set_stylebox("focus", "RichTextLabel", focus);
+ theme->set_stylebox("normal", "RichTextLabel", make_stylebox(tree_bg_png, 3, 3, 3, 3));
theme->set_font("normal_font", "RichTextLabel", default_font);
theme->set_font("bold_font", "RichTextLabel", default_font);
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index 9032b71775..f2a4b2616d 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* default_theme.cpp */
+/* default_theme.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 7de2c85633..14225d945d 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -994,10 +994,10 @@ void Environment::_bind_methods() {
ADD_GROUP("SSAO", "ssao_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,16,0.1"), "set_ssao_radius", "get_ssao_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,9,0.1"), "set_ssao_intensity", "get_ssao_intensity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius2", PROPERTY_HINT_RANGE, "0.0,16,0.1"), "set_ssao_radius2", "get_ssao_radius2");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity2", PROPERTY_HINT_RANGE, "0.0,9,0.1"), "set_ssao_intensity2", "get_ssao_intensity2");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_radius2", "get_ssao_radius2");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity2", "get_ssao_intensity2");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ssao_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ssao_color", "get_ssao_color");
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index d9ccd31f88..ea75748b3d 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -40,7 +40,7 @@ void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, f
return;
}
- float ofs;
+ float ofs = 0.f;
switch (p_align) {
case HALIGN_LEFT: {
ofs = 0;
@@ -51,6 +51,9 @@ void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, f
case HALIGN_RIGHT: {
ofs = p_width - length;
} break;
+ default: {
+ ERR_PRINT("Unknown halignment type");
+ } break;
}
draw(p_canvas_item, p_pos + Point2(ofs, 0), p_text, p_modulate, p_width);
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 77563121df..3d6a10ffc7 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -48,6 +48,19 @@ Ref<Material> Material::get_next_pass() const {
return next_pass;
}
+void Material::set_render_priority(int p_priority) {
+
+ ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN);
+ ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX);
+ render_priority = p_priority;
+ VS::get_singleton()->material_set_render_priority(material, p_priority);
+}
+
+int Material::get_render_priority() const {
+
+ return render_priority;
+}
+
RID Material::get_rid() const {
return material;
@@ -58,12 +71,20 @@ void Material::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass);
ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass);
+ ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Material::set_render_priority);
+ ClassDB::bind_method(D_METHOD("get_render_priority"), &Material::get_render_priority);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass");
+
+ BIND_CONSTANT(RENDER_PRIORITY_MAX);
+ BIND_CONSTANT(RENDER_PRIORITY_MIN);
}
Material::Material() {
material = VisualServer::get_singleton()->material_create();
+ render_priority = 0;
}
Material::~Material() {
@@ -218,6 +239,7 @@ void SpatialMaterial::init_shaders() {
shader_names->anisotropy = "anisotropy_ratio";
shader_names->depth_scale = "depth_scale";
shader_names->subsurface_scattering_strength = "subsurface_scattering_strength";
+ shader_names->transmission = "transmission";
shader_names->refraction = "refraction";
shader_names->point_size = "point_size";
shader_names->uv1_scale = "uv1_scale";
@@ -227,8 +249,8 @@ void SpatialMaterial::init_shaders() {
shader_names->uv1_blend_sharpness = "uv1_blend_sharpness";
shader_names->uv2_blend_sharpness = "uv2_blend_sharpness";
- shader_names->particle_h_frames = "particle_h_frames";
- shader_names->particle_v_frames = "particle_v_frames";
+ shader_names->particles_anim_h_frames = "particles_anim_h_frames";
+ shader_names->particles_anim_v_frames = "particles_anim_v_frames";
shader_names->particles_anim_loop = "particles_anim_loop";
shader_names->depth_min_layers = "depth_min_layers";
shader_names->depth_max_layers = "depth_max_layers";
@@ -255,6 +277,7 @@ void SpatialMaterial::init_shaders() {
shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion";
shader_names->texture_names[TEXTURE_DEPTH] = "texture_depth";
shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering";
+ shader_names->texture_names[TEXTURE_TRANSMISSION] = "texture_transmission";
shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction";
shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask";
shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo";
@@ -331,7 +354,7 @@ void SpatialMaterial::_update_shader() {
}
switch (diffuse_mode) {
case DIFFUSE_LAMBERT: code += ",diffuse_lambert"; break;
- case DIFFUSE_HALF_LAMBERT: code += ",diffuse_half_lambert"; break;
+ case DIFFUSE_LAMBERT_WRAP: code += ",diffuse_lambert_wrap"; break;
case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break;
case DIFFUSE_BURLEY: code += ",diffuse_burley"; break;
case DIFFUSE_TOON: code += ",diffuse_toon"; break;
@@ -347,14 +370,14 @@ void SpatialMaterial::_update_shader() {
if (flags[FLAG_UNSHADED]) {
code += ",unshaded";
}
- if (flags[FLAG_ONTOP]) {
- code += ",ontop";
+ if (flags[FLAG_DISABLE_DEPTH_TEST]) {
+ code += ",depth_test_disable";
}
if (flags[FLAG_USE_VERTEX_LIGHTING]) {
code += ",vertex_lighting";
}
- if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
+ if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) {
code += ",world_vertex_coords";
}
code += ";\n";
@@ -430,6 +453,12 @@ void SpatialMaterial::_update_shader() {
code += "uniform sampler2D texture_subsurface_scattering : hint_white;\n";
}
+ if (features[FEATURE_TRANSMISSION]) {
+
+ code += "uniform vec4 transmission : hint_color;\n";
+ code += "uniform sampler2D texture_transmission : hint_black;\n";
+ }
+
if (features[FEATURE_DEPTH_MAPPING]) {
code += "uniform sampler2D texture_depth : hint_black;\n";
code += "uniform float depth_scale;\n";
@@ -437,10 +466,10 @@ void SpatialMaterial::_update_shader() {
code += "uniform int depth_max_layers;\n";
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "varying vec3 uv1_world_pos;\n";
+ code += "varying vec3 uv1_triplanar_pos;\n";
}
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
- code += "varying vec3 uv2_world_pos;\n";
+ code += "varying vec3 uv2_triplanar_pos;\n";
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "uniform float uv1_blend_sharpness;\n";
@@ -503,8 +532,8 @@ void SpatialMaterial::_update_shader() {
code += "\tint particle_total_frames = particles_anim_h_frames * particles_anim_v_frames;\n";
code += "\tint particle_frame = int(INSTANCE_CUSTOM.y * float(particle_total_frames));\n";
code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0,particle_total_frames-1); else particle_frame=abs(particle_frame)%particle_total_frames;\n";
- //code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n";
- //code += "\tUV+= UV * vec2(float(particle_frame % particles_anim_h_frames),float(particle_frame / particles_anim_v_frames));\n";
+ code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n";
+ code += "\tUV += vec2(float(particle_frame % particles_anim_h_frames) / float(particles_anim_h_frames),float(particle_frame / particles_anim_h_frames) / float(particles_anim_v_frames));\n";
//handle rotation
// code += "\tmat4 rotation = mat4("
} break;
@@ -530,7 +559,7 @@ void SpatialMaterial::_update_shader() {
}
if (detail_uv == DETAIL_UV_2 && !flags[FLAG_UV2_USE_TRIPLANAR]) {
- code += "\tUV2=UV2*uv2_scale+uv2_offset;\n";
+ code += "\tUV2=UV2*uv2_scale.xy+uv2_offset.xy;\n";
}
if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
//generate tangent and binormal in world space
@@ -549,16 +578,16 @@ void SpatialMaterial::_update_shader() {
code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
- code += "\tuv1_world_pos = VERTEX * uv1_scale + uv1_offset;\n";
- code += "\tuv1_world_pos *= vec3(1.0,-1.0, 1.0);\n";
+ code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
+ code += "\tuv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
}
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
- code += "\tuv2_world_pos = VERTEX * uv2_scale + uv2_offset;\n";
- code += "\tuv2_world_pos *= vec3(1.0,-1.0, 1.0);\n";
+ code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
+ code += "\tuv2_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
}
if (grow_enabled) {
@@ -568,11 +597,11 @@ void SpatialMaterial::_update_shader() {
code += "}\n";
code += "\n\n";
if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
- code += "vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_world_pos) {\n";
+ code += "vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n";
code += "\tvec4 samp=vec4(0.0);\n";
- code += "\tsamp+= texture(p_sampler,p_world_pos.xy) * p_weights.z;\n";
- code += "\tsamp+= texture(p_sampler,p_world_pos.xz) * p_weights.y;\n";
- code += "\tsamp+= texture(p_sampler,p_world_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n";
+ code += "\tsamp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n";
+ code += "\tsamp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;\n";
+ code += "\tsamp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n";
code += "\treturn samp;\n";
code += "}\n";
}
@@ -628,7 +657,7 @@ void SpatialMaterial::_update_shader() {
code += "\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
} else {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_world_pos);\n";
+ code += "\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
}
@@ -640,13 +669,13 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_world_pos),metallic_texture_channel);\n";
+ code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n";
} else {
code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
}
code += "\tMETALLIC = metallic_tex * metallic;\n";
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_world_pos),roughness_texture_channel);\n";
+ code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n";
} else {
code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
}
@@ -655,7 +684,7 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_NORMAL_MAPPING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tNORMALMAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_world_pos).rgb;\n";
+ code += "\tNORMALMAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
} else {
code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n";
}
@@ -664,7 +693,7 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_EMISSION]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_world_pos).rgb;\n";
+ code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
} else {
code += "\tvec3 emission_tex = texture(texture_emission,base_uv).rgb;\n";
}
@@ -691,7 +720,7 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_RIM]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec2 rim_tex = triplanar_texture(texture_rim,uv1_power_normal,uv1_world_pos).xy;\n";
+ code += "\tvec2 rim_tex = triplanar_texture(texture_rim,uv1_power_normal,uv1_triplanar_pos).xy;\n";
} else {
code += "\tvec2 rim_tex = texture(texture_rim,base_uv).xy;\n";
}
@@ -701,7 +730,7 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_CLEARCOAT]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec2 clearcoat_tex = triplanar_texture(texture_clearcoat,uv1_power_normal,uv1_world_pos).xy;\n";
+ code += "\tvec2 clearcoat_tex = triplanar_texture(texture_clearcoat,uv1_power_normal,uv1_triplanar_pos).xy;\n";
} else {
code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xy;\n";
}
@@ -711,7 +740,7 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_ANISOTROPY]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec3 anisotropy_tex = triplanar_texture(texture_flowmap,uv1_power_normal,uv1_world_pos).rga;\n";
+ code += "\tvec3 anisotropy_tex = triplanar_texture(texture_flowmap,uv1_power_normal,uv1_triplanar_pos).rga;\n";
} else {
code += "\tvec3 anisotropy_tex = texture(texture_flowmap,base_uv).rga;\n";
}
@@ -722,13 +751,13 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_AMBIENT_OCCLUSION]) {
if (flags[FLAG_AO_ON_UV2]) {
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
- code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_world_pos),ao_texture_channel);\n";
+ code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
} else {
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
}
} else {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_world_pos),ao_texture_channel);\n";
+ code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
} else {
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
}
@@ -738,21 +767,30 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_SUBSURACE_SCATTERING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_world_pos).r;\n";
+ code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
} else {
code += "\tfloat sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n";
}
code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
}
+ if (features[FEATURE_TRANSMISSION]) {
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec3 transmission_tex = triplanar_texture(texture_transmission,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
+ } else {
+ code += "\tvec3 transmission_tex = texture(texture_transmission,base_uv).rgb;\n";
+ }
+ code += "\tTRANSMISSION = (transmission.rgb+transmission_tex);\n";
+ }
+
if (features[FEATURE_DETAIL]) {
bool triplanar = (flags[FLAG_UV1_USE_TRIPLANAR] && detail_uv == DETAIL_UV_1) || (flags[FLAG_UV2_USE_TRIPLANAR] && detail_uv == DETAIL_UV_2);
if (triplanar) {
String tp_uv = detail_uv == DETAIL_UV_1 ? "uv1" : "uv2";
- code += "\tvec4 detail_tex = triplanar_texture(texture_detail_albedo," + tp_uv + "_power_normal," + tp_uv + "_world_pos);\n";
- code += "\tvec4 detail_norm_tex = triplanar_texture(texture_detail_normal," + tp_uv + "_power_normal," + tp_uv + "_world_pos);\n";
+ code += "\tvec4 detail_tex = triplanar_texture(texture_detail_albedo," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n";
+ code += "\tvec4 detail_norm_tex = triplanar_texture(texture_detail_normal," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n";
} else {
String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2";
@@ -994,6 +1032,17 @@ float SpatialMaterial::get_subsurface_scattering_strength() const {
return subsurface_scattering_strength;
}
+void SpatialMaterial::set_transmission(const Color &p_transmission) {
+
+ transmission = p_transmission;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->transmission, transmission);
+}
+
+Color SpatialMaterial::get_transmission() const {
+
+ return transmission;
+}
+
void SpatialMaterial::set_refraction(float p_refraction) {
refraction = p_refraction;
@@ -1159,6 +1208,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
_validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property);
_validate_feature("depth", FEATURE_DEPTH_MAPPING, property);
_validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property);
+ _validate_feature("transmission", FEATURE_TRANSMISSION, property);
_validate_feature("refraction", FEATURE_REFRACTION, property);
_validate_feature("detail", FEATURE_DETAIL, property);
@@ -1281,7 +1331,7 @@ SpatialMaterial::BillboardMode SpatialMaterial::get_billboard_mode() const {
void SpatialMaterial::set_particles_anim_h_frames(int p_frames) {
particles_anim_h_frames = p_frames;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->particle_h_frames, p_frames);
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
}
int SpatialMaterial::get_particles_anim_h_frames() const {
@@ -1291,7 +1341,7 @@ int SpatialMaterial::get_particles_anim_h_frames() const {
void SpatialMaterial::set_particles_anim_v_frames(int p_frames) {
particles_anim_v_frames = p_frames;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->particle_v_frames, p_frames);
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
}
int SpatialMaterial::get_particles_anim_v_frames() const {
@@ -1459,6 +1509,12 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent,
return materials_for_2d[version]->get_rid();
}
+void SpatialMaterial::set_on_top_of_alpha() {
+ set_feature(FEATURE_TRANSPARENT, true);
+ set_render_priority(RENDER_PRIORITY_MAX);
+ set_flag(FLAG_DISABLE_DEPTH_TEST, true);
+}
+
void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
@@ -1503,6 +1559,9 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &SpatialMaterial::set_subsurface_scattering_strength);
ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &SpatialMaterial::get_subsurface_scattering_strength);
+ ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &SpatialMaterial::set_transmission);
+ ClassDB::bind_method(D_METHOD("get_transmission"), &SpatialMaterial::get_transmission);
+
ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction);
ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction);
@@ -1606,8 +1665,9 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_vertex_lighting"), "set_flag", "get_flag", FLAG_USE_VERTEX_LIGHTING);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_on_top"), "set_flag", "get_flag", FLAG_ONTOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_world_triplanar"), "set_flag", "get_flag", FLAG_TRIPLANAR_USE_WORLD);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
@@ -1693,6 +1753,11 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING);
+ ADD_GROUP("Transmission", "transmission_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transmission_enabled"), "set_feature", "get_feature", FEATURE_TRANSMISSION);
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "transmission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_transmission", "get_transmission");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_TRANSMISSION);
+
ADD_GROUP("Refraction", "refraction_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction");
@@ -1730,6 +1795,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION);
BIND_ENUM_CONSTANT(TEXTURE_DEPTH);
BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING);
+ BIND_ENUM_CONSTANT(TEXTURE_TRANSMISSION);
BIND_ENUM_CONSTANT(TEXTURE_REFRACTION);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO);
@@ -1748,6 +1814,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION);
BIND_ENUM_CONSTANT(FEATURE_DEPTH_MAPPING);
BIND_ENUM_CONSTANT(FEATURE_SUBSURACE_SCATTERING);
+ BIND_ENUM_CONSTANT(FEATURE_TRANSMISSION);
BIND_ENUM_CONSTANT(FEATURE_REFRACTION);
BIND_ENUM_CONSTANT(FEATURE_DETAIL);
BIND_ENUM_CONSTANT(FEATURE_MAX);
@@ -1768,7 +1835,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_UNSHADED);
BIND_ENUM_CONSTANT(FLAG_USE_VERTEX_LIGHTING);
- BIND_ENUM_CONSTANT(FLAG_ONTOP);
+ BIND_ENUM_CONSTANT(FLAG_DISABLE_DEPTH_TEST);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR);
BIND_ENUM_CONSTANT(FLAG_SRGB_VERTEX_COLOR);
BIND_ENUM_CONSTANT(FLAG_USE_POINT_SIZE);
@@ -1777,10 +1844,11 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_UV2_USE_TRIPLANAR);
BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2);
BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR);
+ BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT);
- BIND_ENUM_CONSTANT(DIFFUSE_HALF_LAMBERT);
+ BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT_WRAP);
BIND_ENUM_CONSTANT(DIFFUSE_OREN_NAYAR);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
BIND_ENUM_CONSTANT(DIFFUSE_TOON);
@@ -1821,6 +1889,7 @@ SpatialMaterial::SpatialMaterial()
set_anisotropy(0);
set_depth_scale(0.05);
set_subsurface_scattering_strength(0);
+ set_transmission(Color(0, 0, 0));
set_refraction(0.05);
set_line_width(1);
set_point_size(1);
diff --git a/scene/resources/material.h b/scene/resources/material.h
index b82e8d8cbd..4e77ab1ed6 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -48,15 +48,23 @@ class Material : public Resource {
RID material;
Ref<Material> next_pass;
+ int render_priority;
protected:
_FORCE_INLINE_ RID _get_material() const { return material; }
static void _bind_methods();
public:
+ enum {
+ RENDER_PRIORITY_MAX = VS::MATERIAL_RENDER_PRIORITY_MAX,
+ RENDER_PRIORITY_MIN = VS::MATERIAL_RENDER_PRIORITY_MIN,
+ };
void set_next_pass(const Ref<Material> &p_pass);
Ref<Material> get_next_pass() const;
+ void set_render_priority(int p_priority);
+ int get_render_priority() const;
+
virtual RID get_rid() const;
Material();
virtual ~Material();
@@ -104,6 +112,7 @@ public:
TEXTURE_AMBIENT_OCCLUSION,
TEXTURE_DEPTH,
TEXTURE_SUBSURFACE_SCATTERING,
+ TEXTURE_TRANSMISSION,
TEXTURE_REFRACTION,
TEXTURE_DETAIL_MASK,
TEXTURE_DETAIL_ALBEDO,
@@ -127,6 +136,7 @@ public:
FEATURE_AMBIENT_OCCLUSION,
FEATURE_DEPTH_MAPPING,
FEATURE_SUBSURACE_SCATTERING,
+ FEATURE_TRANSMISSION,
FEATURE_REFRACTION,
FEATURE_DETAIL,
FEATURE_MAX
@@ -156,13 +166,14 @@ public:
enum Flags {
FLAG_UNSHADED,
FLAG_USE_VERTEX_LIGHTING,
- FLAG_ONTOP,
+ FLAG_DISABLE_DEPTH_TEST,
FLAG_ALBEDO_FROM_VERTEX_COLOR,
FLAG_SRGB_VERTEX_COLOR,
FLAG_USE_POINT_SIZE,
FLAG_FIXED_SIZE,
FLAG_UV1_USE_TRIPLANAR,
FLAG_UV2_USE_TRIPLANAR,
+ FLAG_TRIPLANAR_USE_WORLD,
FLAG_AO_ON_UV2,
FLAG_USE_ALPHA_SCISSOR,
FLAG_MAX
@@ -170,7 +181,7 @@ public:
enum DiffuseMode {
DIFFUSE_LAMBERT,
- DIFFUSE_HALF_LAMBERT,
+ DIFFUSE_LAMBERT_WRAP,
DIFFUSE_OREN_NAYAR,
DIFFUSE_BURLEY,
DIFFUSE_TOON,
@@ -203,12 +214,12 @@ private:
union MaterialKey {
struct {
- uint64_t feature_mask : 11;
+ uint64_t feature_mask : 12;
uint64_t detail_uv : 1;
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 11;
+ uint64_t flags : 12;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 2;
@@ -277,14 +288,15 @@ private:
StringName anisotropy;
StringName depth_scale;
StringName subsurface_scattering_strength;
+ StringName transmission;
StringName refraction;
StringName point_size;
StringName uv1_scale;
StringName uv1_offset;
StringName uv2_scale;
StringName uv2_offset;
- StringName particle_h_frames;
- StringName particle_v_frames;
+ StringName particles_anim_h_frames;
+ StringName particles_anim_v_frames;
StringName particles_anim_loop;
StringName depth_min_layers;
StringName depth_max_layers;
@@ -328,6 +340,7 @@ private:
float anisotropy;
float depth_scale;
float subsurface_scattering_strength;
+ Color transmission;
float refraction;
float line_width;
float point_size;
@@ -434,6 +447,9 @@ public:
void set_subsurface_scattering_strength(float p_subsurface_scattering_strength);
float get_subsurface_scattering_strength() const;
+ void set_transmission(const Color &p_transmission);
+ Color get_transmission() const;
+
void set_refraction(float p_refraction);
float get_refraction() const;
@@ -511,6 +527,8 @@ public:
void set_alpha_scissor_threshold(float p_treshold);
float get_alpha_scissor_threshold() const;
+ void set_on_top_of_alpha();
+
void set_metallic_texture_channel(TextureChannel p_channel);
TextureChannel get_metallic_texture_channel() const;
void set_roughness_texture_channel(TextureChannel p_channel);
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index 4e1ffd2ab3..e1131e7e3e 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -214,7 +214,7 @@ Vector<int> MeshLibrary::get_item_list() const {
return ret;
}
-int MeshLibrary::find_item_name(const String &p_name) const {
+int MeshLibrary::find_item_by_name(const String &p_name) const {
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
@@ -275,6 +275,9 @@ void MeshLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_shapes", "id"), &MeshLibrary::_get_item_shapes);
ClassDB::bind_method(D_METHOD("get_item_preview", "id"), &MeshLibrary::get_item_preview);
ClassDB::bind_method(D_METHOD("remove_item", "id"), &MeshLibrary::remove_item);
+ ClassDB::bind_method(D_METHOD("remove_item", "id"), &MeshLibrary::remove_item);
+ ClassDB::bind_method(D_METHOD("find_item_by_name", "name"), &MeshLibrary::find_item_by_name);
+
ClassDB::bind_method(D_METHOD("clear"), &MeshLibrary::clear);
ClassDB::bind_method(D_METHOD("get_item_list"), &MeshLibrary::get_item_list);
ClassDB::bind_method(D_METHOD("get_last_unused_item_id"), &MeshLibrary::get_last_unused_item_id);
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 99b6b48d61..c5d23ce50f 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -84,7 +84,7 @@ public:
void clear();
- int find_item_name(const String &p_name) const;
+ int find_item_by_name(const String &p_name) const;
Vector<int> get_item_list() const;
int get_last_unused_item_id() const;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 19fab5d587..c525ca600a 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -145,7 +145,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
node = parent->_get_child_by_name(snames[n.name]);
#ifdef DEBUG_ENABLED
if (!node) {
- WARN_PRINT(String("Node '" + String(ret_nodes[0]->get_path_to(parent)) + "/" + String(snames[n.name]) + "' was modified from inside a instance, but it has vanished.").ascii().get_data());
+ WARN_PRINT(String("Node '" + String(ret_nodes[0]->get_path_to(parent)) + "/" + String(snames[n.name]) + "' was modified from inside an instance, but it has vanished.").ascii().get_data());
}
#endif
}
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index fea5c11dec..14e2ef83f8 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -891,7 +891,7 @@ String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) {
/////////////////////
-Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, Error *r_error) {
+Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
if (r_error)
*r_error = ERR_CANT_OPEN;
@@ -905,7 +905,8 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const
}
Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ String path = p_original_path != "" ? p_original_path : p_path;
+ ria->local_path = ProjectSettings::get_singleton()->localize_path(path);
ria->res_path = ria->local_path;
//ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
ria->open(f);
diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h
index 193bcf7112..a72a62037c 100644
--- a/scene/resources/scene_format_text.h
+++ b/scene/resources/scene_format_text.h
@@ -108,7 +108,7 @@ public:
class ResourceFormatLoaderText : public ResourceFormatLoader {
public:
- virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
+ virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index f646e3667d..b8a0a7864e 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -165,13 +165,13 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NinePatchAxisMode(axis_h), VS::NinePatchAxisMode(axis_v), draw_center, modulate, normal_rid);
}
-void StyleBoxTexture::set_draw_center(bool p_draw) {
+void StyleBoxTexture::set_draw_center(bool p_enabled) {
- draw_center = p_draw;
+ draw_center = p_enabled;
emit_changed();
}
-bool StyleBoxTexture::get_draw_center() const {
+bool StyleBoxTexture::is_draw_center_enabled() const {
return draw_center;
}
@@ -281,7 +281,7 @@ void StyleBoxTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_region_rect"), &StyleBoxTexture::get_region_rect);
ClassDB::bind_method(D_METHOD("set_draw_center", "enable"), &StyleBoxTexture::set_draw_center);
- ClassDB::bind_method(D_METHOD("get_draw_center"), &StyleBoxTexture::get_draw_center);
+ ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &StyleBoxTexture::is_draw_center_enabled);
ClassDB::bind_method(D_METHOD("set_modulate", "color"), &StyleBoxTexture::set_modulate);
ClassDB::bind_method(D_METHOD("get_modulate"), &StyleBoxTexture::get_modulate);
@@ -312,7 +312,7 @@ void StyleBoxTexture::_bind_methods() {
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode");
ADD_GROUP("Modulate", "modulate_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate_color"), "set_modulate", "get_modulate");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "get_draw_center");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled");
BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_STRETCH);
BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE);
@@ -460,14 +460,14 @@ float StyleBoxFlat::get_expand_margin_size(Margin p_expand_margin) const {
return expand_margin[p_expand_margin];
}
-void StyleBoxFlat::set_filled(bool p_filled) {
+void StyleBoxFlat::set_draw_center(bool p_enabled) {
- filled = p_filled;
+ draw_center = p_enabled;
emit_changed();
}
-bool StyleBoxFlat::is_filled() const {
+bool StyleBoxFlat::is_draw_center_enabled() const {
- return filled;
+ return draw_center;
}
void StyleBoxFlat::set_shadow_color(const Color &p_color) {
@@ -691,7 +691,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
style_rect, adapted_border, inner_color, border_color.read().ptr(), corner_detail);
//DRAW INFILL
- if (filled) {
+ if (draw_center) {
int temp_vert_offset = verts.size();
int no_border[4] = { 0, 0, 0, 0 };
draw_ring(verts, indices, colors, style_rect, adapted_corner,
@@ -724,7 +724,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
int aa_border_width[4] = { aa_size, aa_size, aa_size, aa_size };
- if (filled) {
+ if (draw_center) {
if (!blend_border) {
//INFILL AA
draw_ring(verts, indices, colors, style_rect, adapted_corner,
@@ -776,8 +776,8 @@ void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_expand_margin_individual", "size_left", "size_top", "size_right", "size_bottom"), &StyleBoxFlat::set_expand_margin_size_individual);
ClassDB::bind_method(D_METHOD("get_expand_margin", "margin"), &StyleBoxFlat::get_expand_margin_size);
- ClassDB::bind_method(D_METHOD("set_filled", "filled"), &StyleBoxFlat::set_filled);
- ClassDB::bind_method(D_METHOD("is_filled"), &StyleBoxFlat::is_filled);
+ ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &StyleBoxFlat::set_draw_center);
+ ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &StyleBoxFlat::is_draw_center_enabled);
ClassDB::bind_method(D_METHOD("set_shadow_color", "color"), &StyleBoxFlat::set_shadow_color);
ClassDB::bind_method(D_METHOD("get_shadow_color"), &StyleBoxFlat::get_shadow_color);
@@ -796,7 +796,7 @@ void StyleBoxFlat::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "bg_color"), "set_bg_color", "get_bg_color");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filled"), "set_filled", "is_filled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled");
ADD_GROUP("Border Width", "border_width_");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_left", PROPERTY_HINT_RANGE, "0,1024,1"), "set_border_width", "get_border_width", MARGIN_LEFT);
@@ -843,7 +843,7 @@ StyleBoxFlat::StyleBoxFlat() {
border_color.append(Color(0.8, 0.8, 0.8));
blend_border = false;
- filled = true;
+ draw_center = true;
anti_aliased = true;
shadow_size = 0;
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index db41333b7e..3d085f7166 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -117,8 +117,8 @@ public:
void set_normal_map(RES p_normal_map);
RES get_normal_map() const;
- void set_draw_center(bool p_draw);
- bool get_draw_center() const;
+ void set_draw_center(bool p_enabled);
+ bool is_draw_center_enabled() const;
virtual Size2 get_center_size() const;
void set_h_axis_stretch_mode(AxisStretchMode p_mode);
@@ -150,7 +150,7 @@ class StyleBoxFlat : public StyleBox {
int expand_margin[4];
int corner_radius[4];
- bool filled;
+ bool draw_center;
bool blend_border;
bool anti_aliased;
@@ -202,9 +202,9 @@ public:
void set_expand_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom);
float get_expand_margin_size(Margin p_expand_margin) const;
- //FILLED
- void set_filled(bool p_draw);
- bool is_filled() const;
+ //DRAW CENTER
+ void set_draw_center(bool p_enabled);
+ bool is_draw_center_enabled() const;
//SHADOW
void set_shadow_color(const Color &p_color);
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 7342164841..bf89e704bc 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -691,6 +691,17 @@ void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvT
fvTexcOut[1] = v.y;
//fvTexcOut[1]=1.0-v.y;
}
+
+void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
+ const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
+
+ Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
+ Vertex *vtx = &varr[iFace * 3 + iVert]->get();
+
+ vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
+ vtx->binormal = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]);
+}
+
void SurfaceTool::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) {
Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
@@ -715,8 +726,8 @@ void SurfaceTool::generate_tangents() {
mkif.m_getNumVerticesOfFace = mikktGetNumVerticesOfFace;
mkif.m_getPosition = mikktGetPosition;
mkif.m_getTexCoord = mikktGetTexCoord;
- mkif.m_setTSpaceBasic = mikktSetTSpaceBasic;
- mkif.m_setTSpace = NULL;
+ mkif.m_setTSpace = mikktSetTSpaceDefault;
+ mkif.m_setTSpaceBasic = NULL;
SMikkTSpaceContext msc;
msc.m_pInterface = &mkif;
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 2a90c2743d..cdaac643de 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -90,6 +90,8 @@ private:
static void mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert);
static void mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert);
static void mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
+ static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
+ const tbool bIsOrientationPreserving, const int iFace, const int iVert);
protected:
static void _bind_methods();
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 9751d6e711..6a9ded9ea3 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -501,9 +501,9 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
Vector<Ref<Image> > mipmap_images;
int total_size = 0;
- for (int i = 0; i < mipmaps; i++) {
+ for (uint32_t i = 0; i < mipmaps; i++) {
- if (i > 0) {
+ if (i) {
size = f->get_32();
}
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index 992fece85f..1ae0e7b96b 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -37,17 +37,16 @@ Error AudioDriverDummy::init() {
active = false;
thread_exited = false;
exit_thread = false;
- pcm_open = false;
samples_in = NULL;
- mix_rate = 44100;
+ mix_rate = DEFAULT_MIX_RATE;
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_DEF("audio/output_latency", 25);
- buffer_size = next_power_of_2(latency * mix_rate / 1000);
+ int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
- samples_in = memnew_arr(int32_t, buffer_size * channels);
+ samples_in = memnew_arr(int32_t, buffer_frames * channels);
mutex = Mutex::create();
thread = Thread::create(AudioDriverDummy::thread_func, this);
@@ -59,17 +58,15 @@ void AudioDriverDummy::thread_func(void *p_udata) {
AudioDriverDummy *ad = (AudioDriverDummy *)p_udata;
- uint64_t usdelay = (ad->buffer_size / float(ad->mix_rate)) * 1000000;
+ uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000;
while (!ad->exit_thread) {
- if (!ad->active) {
-
- } else {
+ if (ad->active) {
ad->lock();
- ad->audio_server_process(ad->buffer_size, ad->samples_in);
+ ad->audio_server_process(ad->buffer_frames, ad->samples_in);
ad->unlock();
};
diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h
index b3fea59389..90af1961b7 100644
--- a/servers/audio/audio_driver_dummy.h
+++ b/servers/audio/audio_driver_dummy.h
@@ -43,8 +43,8 @@ class AudioDriverDummy : public AudioDriver {
int32_t *samples_in;
static void thread_func(void *p_udata);
- int buffer_size;
+ unsigned int buffer_frames;
unsigned int mix_rate;
SpeakerMode speaker_mode;
@@ -53,7 +53,6 @@ class AudioDriverDummy : public AudioDriver {
bool active;
bool thread_exited;
mutable bool exit_thread;
- bool pcm_open;
public:
const char *get_name() const {
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index 2f160fd7cd..113e356612 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -176,7 +176,7 @@ bool AudioRBResampler::mix(int32_t *p_dest, int p_frames) {
{
- uint32_t read = 0;
+ int read = 0;
switch (channels) {
case 1: read = _resample<1>(p_dest, todo, increment); break;
case 2: read = _resample<2>(p_dest, todo, increment); break;
@@ -189,7 +189,7 @@ bool AudioRBResampler::mix(int32_t *p_dest, int p_frames) {
if (remaining && todo > 0) {
//print_line("fadeout");
- for (int c = 0; c < channels; c++) {
+ for (uint32_t c = 0; c < channels; c++) {
for (int i = 0; i < todo; i++) {
@@ -202,7 +202,7 @@ bool AudioRBResampler::mix(int32_t *p_dest, int p_frames) {
}
//zero out what remains there to avoid glitches
- for (int i = todo * channels; i < int(p_frames) * channels; i++) {
+ for (uint32_t i = todo * channels; i < int(p_frames) * channels; i++) {
p_dest[i] = 0;
}
@@ -250,7 +250,7 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m
rb_write_pos = 0;
//avoid maybe strange noises upon load
- for (int i = 0; i < (rb_len * channels); i++) {
+ for (unsigned int i = 0; i < (rb_len * channels); i++) {
rb[i] = 0;
read_buf[i] = 0;
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp
index 4075bc3e63..76dd585ffa 100644
--- a/servers/audio/effects/audio_effect_chorus.cpp
+++ b/servers/audio/effects/audio_effect_chorus.cpp
@@ -78,7 +78,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A
uint64_t increment = llrint(cycles_to_mix / (double)p_frame_count * (double)(1 << AudioEffectChorus::CYCLES_FRAC));
//check the LFO doesn't read ahead of the write pos
- if ((((int)max_depth_frames) + 10) > delay_frames) { //10 as some threshold to avoid precision stuff
+ if ((((unsigned int)max_depth_frames) + 10) > delay_frames) { //10 as some threshold to avoid precision stuff
delay_frames += (int)max_depth_frames - delay_frames;
delay_frames += 10; //threshold to avoid precision stuff
}
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index c0343399c3..3139c6bb7a 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -155,6 +155,29 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
todo -= to_copy;
to_mix -= to_copy;
}
+
+#ifdef DEBUG_ENABLED
+ if (OS::get_singleton() && OS::get_singleton()->is_stdout_verbose()) {
+ static uint64_t first_ticks = 0;
+ static uint64_t last_ticks = 0;
+ static uint64_t ticks = 0;
+ static int count = 0;
+ static int total = 0;
+
+ ticks = OS::get_singleton()->get_ticks_msec();
+ if ((ticks - first_ticks) > 10 * 1000) {
+ print_line("Audio Driver " + String(AudioDriver::get_singleton()->get_name()) + " average latency: " + itos(total / count) + "ms (frame=" + itos(p_frames) + ")");
+ first_ticks = ticks;
+ total = 0;
+ count = 0;
+ }
+
+ total += ticks - last_ticks;
+ count++;
+
+ last_ticks = ticks;
+ }
+#endif
}
void AudioServer::_mix_step() {
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 05e92ceaf0..13a74856c8 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -54,6 +54,9 @@ public:
SPEAKER_SURROUND_71,
};
+ static const int DEFAULT_MIX_RATE = 44100;
+ static const int DEFAULT_OUTPUT_LATENCY = 15;
+
static AudioDriver *get_singleton();
void set_singleton();
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index ab716a8f6e..3af8b542fa 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "collision_object_sw.h"
+#include "servers/physics/physics_server_sw.h"
#include "space_sw.h"
void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform) {
@@ -39,8 +40,12 @@ void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform
s.bpid = 0; //needs update
shapes.push_back(s);
p_shape->add_owner(this);
- _update_shapes();
- _shapes_changed();
+
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) {
@@ -50,8 +55,11 @@ void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) {
shapes[p_index].shape = p_shape;
p_shape->add_owner(this);
- _update_shapes();
- _shapes_changed();
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_transform) {
@@ -59,8 +67,11 @@ void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_tran
shapes[p_index].xform = p_transform;
shapes[p_index].xform_inv = p_transform.affine_inverse();
- _update_shapes();
- _shapes_changed();
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::remove_shape(ShapeSW *p_shape) {
@@ -90,7 +101,11 @@ void CollisionObjectSW::remove_shape(int p_index) {
shapes[p_index].shape->remove_owner(this);
shapes.remove(p_index);
- _shapes_changed();
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::_set_static(bool p_static) {
@@ -202,7 +217,8 @@ void CollisionObjectSW::_shape_changed() {
_shapes_changed();
}
-CollisionObjectSW::CollisionObjectSW(Type p_type) {
+CollisionObjectSW::CollisionObjectSW(Type p_type)
+ : pending_shape_update_list(this) {
_static = true;
type = p_type;
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index dc988aae86..67a8a44944 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -75,6 +75,8 @@ private:
Transform inv_transform;
bool _static;
+ SelfList<CollisionObjectSW> pending_shape_update_list;
+
void _update_shapes();
protected:
diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp
index c7f66cb7fc..7bef208237 100644
--- a/servers/physics/collision_solver_sw.cpp
+++ b/servers/physics/collision_solver_sw.cpp
@@ -271,7 +271,7 @@ bool CollisionSolverSW::solve_distance_plane(const ShapeSW *p_shape_A, const Tra
bool collided = false;
Vector3 closest;
- real_t closest_d;
+ real_t closest_d = 0;
for (int i = 0; i < support_count; i++) {
diff --git a/servers/physics/gjk_epa.cpp b/servers/physics/gjk_epa.cpp
index 6cea5b003d..0f03bd917a 100644
--- a/servers/physics/gjk_epa.cpp
+++ b/servers/physics/gjk_epa.cpp
@@ -410,8 +410,8 @@ struct GJK
if(l>GJK_SIMPLEX3_EPS)
{
real_t mindist=-1;
- real_t subw[2];
- U subm;
+ real_t subw[2] = { 0 , 0};
+ U subm = 0;
for(U i=0;i<3;++i)
{
if(vec3_dot(*vt[i],vec3_cross(dl[i],n))>0)
@@ -458,7 +458,7 @@ struct GJK
{
real_t mindist=-1;
real_t subw[3];
- U subm;
+ U subm=0;
for(U i=0;i<3;++i)
{
const U j=imd3[i];
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 8d6f7b3fd8..2d46770924 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -763,6 +763,8 @@ void PhysicsServerSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, const
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
body->apply_impulse(p_pos, p_impulse);
body->wakeup();
};
@@ -772,6 +774,8 @@ void PhysicsServerSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_imp
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
body->apply_torque_impulse(p_impulse);
body->wakeup();
};
@@ -781,6 +785,8 @@ void PhysicsServerSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_v
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
Vector3 v = body->get_linear_velocity();
Vector3 axis = p_axis_velocity.normalized();
v -= axis * axis.dot(v);
@@ -793,6 +799,7 @@ void PhysicsServerSW::body_set_axis_lock(RID p_body, BodyAxisLock p_lock) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+
body->set_axis_lock(p_lock);
body->wakeup();
}
@@ -902,6 +909,8 @@ bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, cons
ERR_FAIL_COND_V(!body->get_space(), false);
ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
+ _update_shapes();
+
return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result);
}
@@ -1209,6 +1218,8 @@ bool PhysicsServerSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_a
void PhysicsServerSW::free(RID p_rid) {
+ _update_shapes(); //just in case
+
if (shape_owner.owns(p_rid)) {
ShapeSW *shape = shape_owner.get(p_rid);
@@ -1312,6 +1323,8 @@ void PhysicsServerSW::step(real_t p_step) {
if (!active)
return;
+ _update_shapes();
+
doing_sync = false;
last_step = p_step;
@@ -1409,6 +1422,14 @@ int PhysicsServerSW::get_process_info(ProcessInfo p_info) {
return 0;
}
+void PhysicsServerSW::_update_shapes() {
+
+ while (pending_shape_update_list.first()) {
+ pending_shape_update_list.first()->self()->_shape_changed();
+ pending_shape_update_list.remove(pending_shape_update_list.first());
+ }
+}
+
void PhysicsServerSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) {
CollCbkData *cbk = (CollCbkData *)p_userdata;
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 2e1fa7065a..99ba302acd 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -62,6 +62,10 @@ class PhysicsServerSW : public PhysicsServer {
mutable RID_Owner<JointSW> joint_owner;
//void _clear_query(QuerySW *p_query);
+ friend class CollisionObjectSW;
+ SelfList<CollisionObjectSW>::List pending_shape_update_list;
+ void _update_shapes();
+
public:
static PhysicsServerSW *singleton;
diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp
index f02ff03fcf..1845188089 100644
--- a/servers/physics/shape_sw.cpp
+++ b/servers/physics/shape_sw.cpp
@@ -734,7 +734,7 @@ Vector3 ConvexPolygonShapeSW::get_support(const Vector3 &p_normal) const {
Vector3 n = p_normal;
int vert_support_idx = -1;
- real_t support_max;
+ real_t support_max = 0;
int vertex_count = mesh.vertices.size();
if (vertex_count == 0)
@@ -767,8 +767,8 @@ void ConvexPolygonShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vect
int vc = mesh.vertices.size();
//find vertex first
- real_t max;
- int vtx;
+ real_t max = 0;
+ int vtx = 0;
for (int i = 0; i < vc; i++) {
@@ -1000,7 +1000,7 @@ void FaceShapeSW::project_range(const Vector3 &p_normal, const Transform &p_tran
Vector3 FaceShapeSW::get_support(const Vector3 &p_normal) const {
int vert_support_idx = -1;
- real_t support_max;
+ real_t support_max = 0;
for (int i = 0; i < 3; i++) {
@@ -1154,7 +1154,7 @@ Vector3 ConcavePolygonShapeSW::get_support(const Vector3 &p_normal) const {
Vector3 n = p_normal;
int vert_support_idx = -1;
- real_t support_max;
+ real_t support_max = 0;
for (int i = 0; i < count; i++) {
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index 6c800a4b49..db18995bee 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -640,7 +640,7 @@ BroadPhase2DHashGrid::BroadPhase2DHashGrid() {
cell_size = GLOBAL_DEF("physics/2d/cell_size", 128);
large_object_min_surface = GLOBAL_DEF("physics/2d/large_object_surface_threshold_in_cells", 512);
- for (int i = 0; i < hash_table_size; i++)
+ for (uint32_t i = 0; i < hash_table_size; i++)
hash_table[i] = NULL;
pass = 1;
@@ -649,7 +649,7 @@ BroadPhase2DHashGrid::BroadPhase2DHashGrid() {
BroadPhase2DHashGrid::~BroadPhase2DHashGrid() {
- for (int i = 0; i < hash_table_size; i++) {
+ for (uint32_t i = 0; i < hash_table_size; i++) {
while (hash_table[i]) {
PosBin *pb = hash_table[i];
hash_table[i] = pb->next;
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 006c5fd7b5..e9e7122af3 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -130,9 +130,12 @@ void Physics2DServerSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
if (cbk->valid_dir != Vector2()) {
if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) {
+ cbk->invalid_by_dir++;
return;
}
if (cbk->valid_dir.dot((p_point_A - p_point_B).normalized()) < 0.7071) {
+ cbk->invalid_by_dir++;
+ ;
/* print_line("A: "+p_point_A);
print_line("B: "+p_point_B);
print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B))));
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index 7d3c589fa9..dd310d7a93 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -74,6 +74,7 @@ public:
real_t valid_depth;
int max;
int amount;
+ int invalid_by_dir;
Vector2 *ptr;
};
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 9b2e586993..779f0d54ac 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -30,8 +30,8 @@
#include "space_2d_sw.h"
#include "collision_solver_2d_sw.h"
+#include "pair.h"
#include "physics_2d_server_sw.h"
-
_FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) {
if ((p_object->get_collision_layer() & p_collision_layer) == 0)
@@ -517,6 +517,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
body_aabb = body_aabb.grow(p_margin);
+ static const int max_excluded_shape_pairs = 32;
+ Pair<Shape2DSW *, Shape2DSW *> excluded_shape_pairs[max_excluded_shape_pairs];
+ int excluded_shape_pair_count = 0;
+
Transform2D body_transform = p_from;
{
@@ -532,6 +536,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
cbk.max = max_results;
cbk.amount = 0;
cbk.ptr = sr;
+ cbk.invalid_by_dir = 0;
+ excluded_shape_pair_count = 0; //last step is the one valid
Physics2DServerSW::CollCbkData *cbkptr = &cbk;
CollisionSolver2DSW::CallbackResult cbkres = Physics2DServerSW::_shape_col_cbk;
@@ -555,14 +561,25 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
cbk.valid_depth = p_margin; //only valid depth is the collision margin
+ cbk.invalid_by_dir = 0;
+
} else {
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
+ cbk.invalid_by_dir = 0;
}
- if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
+ Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
+ if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
collided = cbk.amount > 0;
}
+
+ if (!collided && cbk.invalid_by_dir > 0) {
+ //this shape must be excluded
+ if (excluded_shape_pair_count < max_excluded_shape_pairs) {
+ excluded_shape_pairs[excluded_shape_pair_count++] = Pair<Shape2DSW *, Shape2DSW *>(body_shape, against_shape);
+ }
+ }
}
}
@@ -622,15 +639,31 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
+ Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
+
+ bool excluded = false;
+
+ for (int k = 0; k < excluded_shape_pair_count; k++) {
+
+ if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) {
+ excluded = true;
+ break;
+ }
+ }
+
+ if (excluded) {
+
+ continue;
+ }
Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
//test initial overlap, does it collide if going all the way?
- if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
+ if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
continue;
}
//test initial overlap
- if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
+ if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
if (col_obj->is_shape_set_as_one_way_collision(j)) {
continue;
@@ -650,7 +683,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
real_t ofs = (low + hi) * 0.5;
Vector2 sep = mnormal; //important optimization for this to work fast enough
- bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, &sep, 0);
+ bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_xform, Vector2(), NULL, NULL, &sep, 0);
if (collided) {
@@ -669,7 +702,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
cbk.amount = 0;
cbk.ptr = cd;
cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
- ;
+
cbk.valid_depth = 10e20;
Vector2 sep = mnormal; //important optimization for this to work fast enough
@@ -738,6 +771,19 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
+ Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
+
+ bool excluded = false;
+ for (int k = 0; k < excluded_shape_pair_count; k++) {
+
+ if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) {
+ excluded = true;
+ break;
+ }
+ }
+ if (excluded)
+ continue;
+
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
rcd.valid_dir = body_shape_xform.get_axis(1).normalized();
@@ -749,7 +795,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
rcd.object = col_obj;
rcd.shape = shape_idx;
- bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
+ bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
if (!sc)
continue;
}
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index 5097e0a5d2..d4e37be882 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -75,7 +75,7 @@ void PhysicsDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_total_angular_damp"), &PhysicsDirectBodyState::get_total_angular_damp);
ClassDB::bind_method(D_METHOD("get_center_of_mass"), &PhysicsDirectBodyState::get_center_of_mass);
- ClassDB::bind_method(D_METHOD("get_principal_inetria_axes"), &PhysicsDirectBodyState::get_principal_inertia_axes);
+ ClassDB::bind_method(D_METHOD("get_principal_inertia_axes"), &PhysicsDirectBodyState::get_principal_inertia_axes);
ClassDB::bind_method(D_METHOD("get_inverse_mass"), &PhysicsDirectBodyState::get_inverse_mass);
ClassDB::bind_method(D_METHOD("get_inverse_inertia"), &PhysicsDirectBodyState::get_inverse_inertia);
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 9e4acac25d..187a0b180b 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -213,6 +213,7 @@ public:
virtual RID material_create() = 0;
+ virtual void material_set_render_priority(RID p_material, int priority) = 0;
virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
virtual RID material_get_shader(RID p_shader_material) const = 0;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 6e42143246..0684cb1701 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -165,6 +165,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"CF_BREAK",
"CF_CONTINUE",
"CF_RETURN",
+ "CF_DISCARD",
"BRACKET_OPEN",
"BRACKET_CLOSE",
"CURLY_BRACKET_OPEN",
@@ -1041,12 +1042,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
}
} break;
case OP_ASSIGN: {
-
- if (p_op->arguments[0]->type != Node::TYPE_MEMBER && p_op->arguments[0]->type != Node::TYPE_VARIABLE) {
- valid = false;
- break;
- }
-
DataType na = p_op->arguments[0]->get_datatype();
DataType nb = p_op->arguments[1]->get_datatype();
valid = na == nb;
@@ -2591,7 +2586,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
bool index_valid = false;
- DataType member_type;
+ DataType member_type = TYPE_VOID;
switch (expr->get_datatype()) {
case TYPE_BVEC2:
@@ -2958,7 +2953,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (expression[next_op + 1].is_op) {
// this is not invalid and can really appear
// but it becomes invalid anyway because no binary op
- // can be followed by an unary op in a valid combination,
+ // can be followed by a unary op in a valid combination,
// due to how precedence works, unaries will always disappear first
_set_error("Parser bug..");
@@ -3297,6 +3292,34 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
}
p_block->statements.push_back(flow);
+ } else if (tk.type == TK_CF_DISCARD) {
+
+ //check return type
+ BlockNode *b = p_block;
+ while (b && !b->parent_function) {
+ b = b->parent_block;
+ }
+ if (!b) {
+ _set_error("Bug");
+ return ERR_BUG;
+ }
+
+ if (!b->parent_function->can_discard) {
+ _set_error("Use of 'discard' is not allowed here.");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *flow = alloc_node<ControlFlowNode>();
+ flow->flow_op = FLOW_OP_DISCARD;
+
+ pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ //all is good
+ _set_error("Expected ';' after discard");
+ }
+
+ p_block->statements.push_back(flow);
} else {
@@ -3321,12 +3344,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
return OK;
}
-Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
Token tk = _get_token();
if (tk.type != TK_SHADER_TYPE) {
- _set_error("Expected 'shader_type' at the begining of shader.");
+ _set_error("Expected 'shader_type' at the beginning of shader.");
return ERR_PARSE_ERROR;
}
@@ -3658,7 +3681,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataTy
Map<StringName, DataType> builtin_types;
if (p_functions.has(name)) {
- builtin_types = p_functions[name];
+ builtin_types = p_functions[name].built_ins;
}
ShaderNode::Function function;
@@ -3822,7 +3845,7 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
return String();
}
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
clear();
@@ -3839,7 +3862,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<St
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
clear();
@@ -3866,7 +3889,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<S
} break;
case COMPLETION_MAIN_FUNCTION: {
- for (const Map<StringName, Map<StringName, DataType> >::Element *E = p_functions.front(); E; E = E->next()) {
+ for (const Map<StringName, FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) {
r_options->push_back(E->key());
}
@@ -3907,7 +3930,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<S
if (comp_ident && skip_function != StringName() && p_functions.has(skip_function)) {
- for (Map<StringName, DataType>::Element *E = p_functions[skip_function].front(); E; E = E->next()) {
+ for (Map<StringName, DataType>::Element *E = p_functions[skip_function].built_ins.front(); E; E = E->next()) {
matches.insert(E->key());
}
}
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index f4be6fff39..f00b4c5a97 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -118,6 +118,7 @@ public:
TK_CF_BREAK,
TK_CF_CONTINUE,
TK_CF_RETURN,
+ TK_CF_DISCARD,
TK_BRACKET_OPEN,
TK_BRACKET_CLOSE,
TK_CURLY_BRACKET_OPEN,
@@ -244,7 +245,8 @@ public:
FLOW_OP_DO,
FLOW_OP_BREAK,
FLOW_OP_SWITCH,
- FLOW_OP_CONTINUE
+ FLOW_OP_CONTINUE,
+ FLOW_OP_DISCARD
};
@@ -387,10 +389,12 @@ public:
DataPrecision return_precision;
Vector<Argument> arguments;
BlockNode *body;
+ bool can_discard;
FunctionNode() {
type = TYPE_FUNCTION;
return_precision = PRECISION_DEFAULT;
+ can_discard = false;
}
};
@@ -499,6 +503,11 @@ public:
static void get_keyword_list(List<String> *r_keywords);
static void get_builtin_funcs(List<String> *r_keywords);
+ struct FunctionInfo {
+ Map<StringName, DataType> built_ins;
+ bool can_discard;
+ };
+
private:
struct KeyWord {
TokenType token;
@@ -591,7 +600,7 @@ private:
Error _parse_block(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
- Error _parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
+ Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
public:
//static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
@@ -599,8 +608,8 @@ public:
void clear();
static String get_shader_type(const String &p_code);
- Error compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
- Error complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint);
+ Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
+ Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 340cbf5e7b..91c5d430f5 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "shader_types.h"
-const Map<StringName, Map<StringName, ShaderLanguage::DataType> > &ShaderTypes::get_functions(VS::ShaderMode p_mode) {
+const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(VS::ShaderMode p_mode) {
return shader_modes[p_mode].functions;
}
@@ -50,72 +50,74 @@ ShaderTypes::ShaderTypes() {
/*************** SPATIAL ***********************/
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_VERTEX"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_BONES"] = ShaderLanguage::TYPE_IVEC4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;
-
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["POSITION"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["VERTEX"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["TANGENT"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["BINORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["UV2"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INSTANCE_ID"] = ShaderLanguage::TYPE_INT;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INSTANCE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["SRC_VERTEX"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["SRC_NORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["SRC_BONES"] = ShaderLanguage::TYPE_IVEC4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["SRC_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;
+
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["POSITION"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["UV2"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = ShaderLanguage::TYPE_INT;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].can_discard = false;
//builtins
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["MODELVIEW_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
-
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["VERTEX"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["FRAGCOORD"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["FRONT_FACING"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["TANGENT"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["BINORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["UV2"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALBEDO"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["METALLIC"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM_TINT"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["CLEARCOAT"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["CLEARCOAT_GLOSS"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["AO"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["EMISSION"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DISCARD"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SIDE"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT;
-
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["MODELVIEW_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
+
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRONT_FACING"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV2"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALBEDO"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["METALLIC"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SPECULAR"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["RIM"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["RIM_TINT"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT_GLOSS"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TRANSMISSION"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SIDE"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT;
+
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].can_discard = true;
shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_mix");
shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_add");
@@ -127,15 +129,16 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_never");
shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_alpha_prepass");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_test_disable");
+
shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_front");
shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_back");
shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_disabled");
shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("ontop");
shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_half_lambert");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert_wrap");
shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_oren_nayar");
shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_burley");
shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_toon");
@@ -153,52 +156,55 @@ ShaderTypes::ShaderTypes() {
/************ CANVAS ITEM **************************/
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["SRC_VERTEX"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["VERTEX"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["VERTEX_COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT;
-
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["EXTRA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["PARTICLE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
-
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SRC_COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["FRAGCOORD"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
-
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["POSITION"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_UV"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_SHADOW"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["SHADOW"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["SRC_VERTEX"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX_COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT;
+
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["EXTRA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["PARTICLE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].can_discard = false;
+
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SRC_COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["FRAGCOORD"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].can_discard = true;
+
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POSITION"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_SHADOW"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].can_discard = true;
shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_vertex_transform");
@@ -213,20 +219,21 @@ ShaderTypes::ShaderTypes() {
/************ PARTICLES **************************/
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["MASS"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["ACTIVE"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["RESTART"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["CUSTOM"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["LIFETIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["DELTA"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["NUMBER"] = ShaderLanguage::TYPE_UINT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["INDEX"] = ShaderLanguage::TYPE_INT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["EMISSION_TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["RANDOM_SEED"] = ShaderLanguage::TYPE_UINT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["RESTART"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["LIFETIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["DELTA"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["NUMBER"] = ShaderLanguage::TYPE_UINT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["INDEX"] = ShaderLanguage::TYPE_INT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["EMISSION_TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["RANDOM_SEED"] = ShaderLanguage::TYPE_UINT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"].can_discard = false;
shader_modes[VS::SHADER_PARTICLES].modes.insert("billboard");
shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_force");
diff --git a/servers/visual/shader_types.h b/servers/visual/shader_types.h
index 4f4c7c5352..725217ba2e 100644
--- a/servers/visual/shader_types.h
+++ b/servers/visual/shader_types.h
@@ -36,7 +36,7 @@ class ShaderTypes {
struct Type {
- Map<StringName, Map<StringName, ShaderLanguage::DataType> > functions;
+ Map<StringName, ShaderLanguage::FunctionInfo> functions;
Set<String> modes;
};
@@ -49,7 +49,7 @@ class ShaderTypes {
public:
static ShaderTypes *get_singleton() { return singleton; }
- const Map<StringName, Map<StringName, ShaderLanguage::DataType> > &get_functions(VS::ShaderMode p_mode);
+ const Map<StringName, ShaderLanguage::FunctionInfo> &get_functions(VS::ShaderMode p_mode);
const Set<String> &get_modes(VS::ShaderMode p_mode);
const Set<String> &get_types();
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 774b692a22..3953bc5f48 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -690,6 +690,7 @@ public:
BIND3(material_set_param, RID, const StringName &, const Variant &)
BIND2RC(Variant, material_get_param, RID, const StringName &)
+ BIND2(material_set_render_priority, RID, int)
BIND2(material_set_line_width, RID, float)
BIND2(material_set_next_pass, RID, RID)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 95ac876ec0..0d70b7fc0e 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -948,13 +948,13 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
//z_vec points agsint the camera, like in default opengl
- float x_min, x_max;
- float y_min, y_max;
- float z_min, z_max;
+ float x_min = 0.f, x_max = 0.f;
+ float y_min = 0.f, y_max = 0.f;
+ float z_min = 0.f, z_max = 0.f;
- float x_min_cam, x_max_cam;
- float y_min_cam, y_max_cam;
- float z_min_cam, z_max_cam;
+ float x_min_cam = 0.f, x_max_cam = 0.f;
+ float y_min_cam = 0.f, y_max_cam = 0.f;
+ float z_min_cam = 0.f, z_max_cam = 0.f;
float bias_scale = 1.0;
@@ -1434,7 +1434,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
}
ins->depth = near_plane.distance_to(ins->transform.origin);
- ins->depth_layer = CLAMP(int(ins->depth * 8 / z_far), 0, 7);
+ ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
}
if (!keep) {
@@ -1473,9 +1473,10 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
//check shadow..
- if (light && p_shadow_atlas.is_valid() && VSG::storage->light_has_shadow(E->get()->base)) {
- lights_with_shadow[directional_shadow_count++] = E->get();
-
+ if (light) {
+ if (p_shadow_atlas.is_valid() && VSG::storage->light_has_shadow(E->get()->base)) {
+ lights_with_shadow[directional_shadow_count++] = E->get();
+ }
//add to list
directional_light_ptr[directional_light_count++] = light->instance;
}
@@ -1502,7 +1503,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
- float coverage;
+ float coverage = 0.f;
{ //compute coverage
@@ -1686,7 +1687,7 @@ bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int
void VisualServerScene::_gi_probe_fill_local_data(int p_idx, int p_level, int p_x, int p_y, int p_z, const GIProbeDataCell *p_cell, const GIProbeDataHeader *p_header, InstanceGIProbeData::LocalData *p_local_data, Vector<uint32_t> *prev_cell) {
- if (p_level == p_header->cell_subdiv - 1) {
+ if ((uint32_t)p_level == p_header->cell_subdiv - 1) {
Vector3 emission;
emission.x = (p_cell[p_idx].emission >> 24) / 255.0;
@@ -1797,9 +1798,9 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) {
}
for (int i = 0; i < (int)header->cell_subdiv; i++) {
- uint32_t x = header->width >> i;
- uint32_t y = header->height >> i;
- uint32_t z = header->depth >> i;
+ int x = header->width >> i;
+ int y = header->height >> i;
+ int z = header->depth >> i;
//create and clear mipmap
PoolVector<uint8_t> mipmap;
@@ -1895,7 +1896,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) {
uint8_t alpha_block[4][4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
- for (int j = 0; j < k.source_count; j++) {
+ for (uint32_t j = 0; j < k.source_count; j++) {
int alpha = (cells[k.sources[j]].level_alpha >> 8) & 0xFF;
if (alpha < min_alpha)
@@ -2388,7 +2389,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
Vector3 colors[16];
- for (int j = 0; j < b.source_count; j++) {
+ for (uint32_t j = 0; j < b.source_count; j++) {
colors[j].x = (local_data[b.sources[j]].energy[0] / float(probe_data->dynamic.bake_dynamic_range)) / 1024.0;
colors[j].y = (local_data[b.sources[j]].energy[1] / float(probe_data->dynamic.bake_dynamic_range)) / 1024.0;
@@ -2402,8 +2403,8 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
if (b.source_count == 16) {
//all cells are used so, find minmax between them
int further_apart[2] = { 0, 0 };
- for (int j = 0; j < b.source_count; j++) {
- for (int k = j + 1; k < b.source_count; k++) {
+ for (uint32_t j = 0; j < b.source_count; j++) {
+ for (uint32_t k = j + 1; k < b.source_count; k++) {
float d = colors[j].distance_squared_to(colors[k]);
if (d > distance) {
distance = d;
@@ -2423,12 +2424,12 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
//average all colors first
Vector3 average;
- for (int j = 0; j < b.source_count; j++) {
+ for (uint32_t j = 0; j < b.source_count; j++) {
average += colors[j];
}
average.normalize();
//find max distance in normal from average
- for (int j = 0; j < b.source_count; j++) {
+ for (uint32_t j = 0; j < b.source_count; j++) {
float d = average.dot(colors[j]);
distance = MAX(d, distance);
}
@@ -2458,7 +2459,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
Vector3 dir = (to - from).normalized();
- for (int j = 0; j < b.source_count; j++) {
+ for (uint32_t j = 0; j < b.source_count; j++) {
float d = (colors[j] - from).dot(dir) / distance;
indices[j] = int(d * 3 + 0.5);
@@ -2468,7 +2469,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
indices[j] = index_swap[CLAMP(indices[j], 0, 3)];
}
} else {
- for (int j = 0; j < b.source_count; j++) {
+ for (uint32_t j = 0; j < b.source_count; j++) {
indices[j] = 0;
}
}
@@ -2477,7 +2478,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
uint32_t index_block[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- for (int j = 0; j < b.source_count; j++) {
+ for (uint32_t j = 0; j < b.source_count; j++) {
int x = local_data[b.sources[j]].pos[0] % 4;
int y = local_data[b.sources[j]].pos[1] % 4;
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 7143178b04..f24049be92 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -128,6 +128,7 @@ public:
FUNC3(material_set_param, RID, const StringName &, const Variant &)
FUNC2RC(Variant, material_get_param, RID, const StringName &)
+ FUNC2(material_set_render_priority, RID, int)
FUNC2(material_set_line_width, RID, float)
FUNC2(material_set_next_pass, RID, RID)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 777feffb06..67b847d127 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1422,6 +1422,7 @@ Array VisualServer::mesh_surface_get_arrays(RID p_mesh, int p_surface) const {
void VisualServer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("force_draw"), &VisualServer::draw);
ClassDB::bind_method(D_METHOD("texture_create"), &VisualServer::texture_create);
ClassDB::bind_method(D_METHOD("texture_create_from_image", "image", "flags"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
//ClassDB::bind_method(D_METHOD("texture_allocate"),&VisualServer::texture_allocate,DEFVAL( TEXTURE_FLAGS_DEFAULT ) );
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 9f2d685531..d516013ee2 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -166,6 +166,11 @@ public:
/* COMMON MATERIAL API */
+ enum {
+ MATERIAL_RENDER_PRIORITY_MIN = -128,
+ MATERIAL_RENDER_PRIORITY_MAX = 127,
+
+ };
virtual RID material_create() = 0;
virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
@@ -174,6 +179,8 @@ public:
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0;
virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
+ virtual void material_set_render_priority(RID p_material, int priority) = 0;
+
virtual void material_set_line_width(RID p_material, float p_width) = 0;
virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0;
@@ -358,6 +365,7 @@ public:
LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
LIGHT_PARAM_SHADOW_NORMAL_BIAS,
LIGHT_PARAM_SHADOW_BIAS,
+ LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
LIGHT_PARAM_MAX
};
@@ -823,6 +831,7 @@ public:
CANVAS_LIGHT_FILTER_NONE,
CANVAS_LIGHT_FILTER_PCF3,
CANVAS_LIGHT_FILTER_PCF5,
+ CANVAS_LIGHT_FILTER_PCF7,
CANVAS_LIGHT_FILTER_PCF9,
CANVAS_LIGHT_FILTER_PCF13,
};
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 56b4a07d9b..76d51d7066 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -51,9 +51,23 @@ Files extracted from upstream source:
## fonts
-- Upstream: ?
+### Noto Sans
-TODO.
+- Upstream: https://github.com/googlei18n/noto-fonts
+- Version: 1.06
+- License: OFL-1.1
+
+Use UI font if exists, because it has tight vertial metrix and good for UI.
+
+### Adobe Source Code Pro Regular
+
+- Upstream: https://github.com/adobe-fonts/source-code-pro
+- Version: 2.030
+- License: OFL-1.1
+
+### DroidSans*.ttf
+
+- Upstream: ?
## freetype
@@ -321,6 +335,18 @@ Files extracted from upstream source:
- celt/ and silk/ subfolders
- COPYING
+## pcre2
+
+- Upstream: http://www.pcre.org/
+- Version: 10.23
+- License: BSD-3-Clause
+
+Files extracted from upstream source:
+
+- Files listed in NON-AUTOTOOLS-BUILD steps 1-4
+- All .h files in src/
+- src/pcre2_jit_*.c and src/sljit/*
+- AUTHORS and COPYING
## pvrtccompressor
diff --git a/thirdparty/fonts/DroidSans.ttf b/thirdparty/fonts/DroidSans.ttf
deleted file mode 100644
index 767c63ad00..0000000000
--- a/thirdparty/fonts/DroidSans.ttf
+++ /dev/null
Binary files differ
diff --git a/thirdparty/fonts/DroidSansArabic.ttf b/thirdparty/fonts/DroidSansArabic.ttf
deleted file mode 100644
index 660e2a9916..0000000000
--- a/thirdparty/fonts/DroidSansArabic.ttf
+++ /dev/null
Binary files differ
diff --git a/thirdparty/fonts/DroidSansHebrew.ttf b/thirdparty/fonts/DroidSansHebrew.ttf
deleted file mode 100644
index 8d77e3e4cf..0000000000
--- a/thirdparty/fonts/DroidSansHebrew.ttf
+++ /dev/null
Binary files differ
diff --git a/thirdparty/fonts/LICENSE.Noto.txt b/thirdparty/fonts/LICENSE.Noto.txt
new file mode 100644
index 0000000000..d952d62c06
--- /dev/null
+++ b/thirdparty/fonts/LICENSE.Noto.txt
@@ -0,0 +1,92 @@
+This Font Software is licensed under the SIL Open Font License,
+Version 1.1.
+
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font
+creation efforts of academic and linguistic communities, and to
+provide a free and open framework in which fonts may be shared and
+improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply to
+any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software
+components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to,
+deleting, or substituting -- in part or in whole -- any of the
+components of the Original Version, by changing formats or by porting
+the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed,
+modify, redistribute, and sell modified and unmodified copies of the
+Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in
+Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the
+corresponding Copyright Holder. This restriction only applies to the
+primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created using
+the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/thirdparty/fonts/NotoNaskhArabicUI_Regular.ttf b/thirdparty/fonts/NotoNaskhArabicUI_Regular.ttf
new file mode 100644
index 0000000000..67713c697e
--- /dev/null
+++ b/thirdparty/fonts/NotoNaskhArabicUI_Regular.ttf
Binary files differ
diff --git a/thirdparty/fonts/NotoSansHebrew_Regular.ttf b/thirdparty/fonts/NotoSansHebrew_Regular.ttf
new file mode 100644
index 0000000000..5027f5c228
--- /dev/null
+++ b/thirdparty/fonts/NotoSansHebrew_Regular.ttf
Binary files differ
diff --git a/thirdparty/fonts/DroidSansThai.ttf b/thirdparty/fonts/NotoSansThaiUI_Regular.ttf
index f849baeff9..9c50a1b8f5 100644
--- a/thirdparty/fonts/DroidSansThai.ttf
+++ b/thirdparty/fonts/NotoSansThaiUI_Regular.ttf
Binary files differ
diff --git a/thirdparty/fonts/NotoSansUI_Regular.ttf b/thirdparty/fonts/NotoSansUI_Regular.ttf
new file mode 100644
index 0000000000..65b29fcff1
--- /dev/null
+++ b/thirdparty/fonts/NotoSansUI_Regular.ttf
Binary files differ
diff --git a/thirdparty/fonts/source_code_pro.otf b/thirdparty/fonts/source_code_pro.otf
index 4e3b9d0bcd..1bae0027ff 100644
--- a/thirdparty/fonts/source_code_pro.otf
+++ b/thirdparty/fonts/source_code_pro.otf
Binary files differ
diff --git a/thirdparty/pcre2/AUTHORS b/thirdparty/pcre2/AUTHORS
new file mode 100644
index 0000000000..e056ad6868
--- /dev/null
+++ b/thirdparty/pcre2/AUTHORS
@@ -0,0 +1,36 @@
+THE MAIN PCRE2 LIBRARY CODE
+---------------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2017 University of Cambridge
+All rights reserved
+
+
+PCRE2 JUST-IN-TIME COMPILATION SUPPORT
+--------------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2010-2017 Zoltan Herczeg
+All rights reserved.
+
+
+STACK-LESS JUST-IN-TIME COMPILER
+--------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2009-2017 Zoltan Herczeg
+All rights reserved.
+
+####
diff --git a/thirdparty/pcre2/LICENCE b/thirdparty/pcre2/LICENCE
new file mode 100644
index 0000000000..402fe2435c
--- /dev/null
+++ b/thirdparty/pcre2/LICENCE
@@ -0,0 +1,83 @@
+PCRE2 LICENCE
+-------------
+
+PCRE2 is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 10 of PCRE2 is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE2, supplied in the "doc"
+directory, is distributed under the same terms as the software itself. The data
+in the testdata directory is not copyrighted and is in the public domain.
+
+The basic library functions are written in C and are freestanding. Also
+included in the distribution is a just-in-time compiler that can be used to
+optimize pattern matching. This is an optional feature that can be omitted when
+the library is built.
+
+
+THE BASIC LIBRARY FUNCTIONS
+---------------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2017 University of Cambridge
+All rights reserved.
+
+
+PCRE2 JUST-IN-TIME COMPILATION SUPPORT
+--------------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2010-2017 Zoltan Herczeg
+All rights reserved.
+
+
+STACK-LESS JUST-IN-TIME COMPILER
+--------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2009-2017 Zoltan Herczeg
+All rights reserved.
+
+
+THE "BSD" LICENCE
+-----------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of any
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+End
diff --git a/thirdparty/pcre2/src/config.h b/thirdparty/pcre2/src/config.h
new file mode 100644
index 0000000000..3315b7770e
--- /dev/null
+++ b/thirdparty/pcre2/src/config.h
@@ -0,0 +1,359 @@
+/* src/config.h. Generated from config.h.in by configure. */
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* PCRE2 is written in Standard C, but there are a few non-standard things it
+can cope with, allowing it to run on SunOS4 and other "close to standard"
+systems.
+
+In environments that support the GNU autotools, config.h.in is converted into
+config.h by the "configure" script. In environments that use CMake,
+config-cmake.in is converted into config.h. If you are going to build PCRE2 "by
+hand" without using "configure" or CMake, you should copy the distributed
+config.h.generic to config.h, and edit the macro definitions to be the way you
+need them. You must then add -DHAVE_CONFIG_H to all of your compile commands,
+so that config.h is included at the start of every source.
+
+Alternatively, you can avoid editing by using -D on the compiler command line
+to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,
+but if you do, default values will be taken from config.h for non-boolean
+macros that are not defined on the command line.
+
+Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be defined
+(conventionally to 1) for TRUE, and not defined at all for FALSE. All such
+macros are listed as a commented #undef in config.h.generic. Macros such as
+MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are
+surrounded by #ifndef/#endif lines so that the value can be overridden by -D.
+
+PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if
+HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make
+sure both macros are undefined; an emulation function will then be used. */
+
+/* By default, the \R escape sequence matches any Unicode line ending
+ character or sequence of characters. If BSR_ANYCRLF is defined (to any
+ value), this is changed so that backslash-R matches only CR, LF, or CRLF.
+ The build-time default can be overridden by the user of PCRE2 at runtime.
+ */
+/* #undef BSR_ANYCRLF */
+
+/* If you are compiling for a system that uses EBCDIC instead of ASCII
+ character codes, define this macro to any value. When EBCDIC is set, PCRE2
+ assumes that all input strings are in EBCDIC. If you do not define this
+ macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It
+ is not possible to build a version of PCRE2 that supports both EBCDIC and
+ UTF-8/16/32. */
+/* #undef EBCDIC */
+
+/* In an EBCDIC environment, define this macro to any value to arrange for the
+ NL character to be 0x25 instead of the default 0x15. NL plays the role that
+ LF does in an ASCII/Unicode environment. */
+/* #undef EBCDIC_NL25 */
+
+/* Define to 1 if you have the `bcopy' function. */
+/* #undef HAVE_BCOPY */
+
+/* Define to 1 if you have the <bzlib.h> header file. */
+/* #undef HAVE_BZLIB_H */
+
+/* Define to 1 if you have the <dirent.h> header file. */
+/* #undef HAVE_DIRENT_H */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define to 1 if you have the <editline/readline.h> header file. */
+/* #undef HAVE_EDITLINE_READLINE_H */
+
+/* Define to 1 if you have the <edit/readline/readline.h> header file. */
+/* #undef HAVE_EDIT_READLINE_READLINE_H */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+/* #undef HAVE_INTTYPES_H */
+
+/* Define to 1 if you have the <limits.h> header file. */
+/* #undef HAVE_LIMITS_H */
+
+/* Define to 1 if you have the `memmove' function. */
+/* #undef HAVE_MEMMOVE */
+
+/* Define to 1 if you have the <memory.h> header file. */
+/* #undef HAVE_MEMORY_H */
+
+/* Define to 1 if you have the `mkostemp' function. */
+/* #undef HAVE_MKOSTEMP */
+
+/* Define if you have POSIX threads libraries and header files. */
+/* #undef HAVE_PTHREAD */
+
+/* Have PTHREAD_PRIO_INHERIT. */
+/* #undef HAVE_PTHREAD_PRIO_INHERIT */
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+/* #undef HAVE_READLINE_HISTORY_H */
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+/* #undef HAVE_READLINE_READLINE_H */
+
+/* Define to 1 if you have the `secure_getenv' function. */
+/* #undef HAVE_SECURE_GETENV */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+/* #undef HAVE_STDLIB_H */
+
+/* Define to 1 if you have the `strerror' function. */
+/* #undef HAVE_STRERROR */
+
+/* Define to 1 if you have the <strings.h> header file. */
+/* #undef HAVE_STRINGS_H */
+
+/* Define to 1 if you have the <string.h> header file. */
+/* #undef HAVE_STRING_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+/* #undef HAVE_SYS_STAT_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+/* #undef HAVE_SYS_TYPES_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+/* #undef HAVE_SYS_WAIT_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Define to 1 if the compiler supports simple visibility declarations. */
+/* #undef HAVE_VISIBILITY */
+
+/* Define to 1 if you have the <windows.h> header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the <zlib.h> header file. */
+/* #undef HAVE_ZLIB_H */
+
+/* PCRE2 uses recursive function calls to handle backtracking while matching.
+ This can sometimes be a problem on systems that have stacks of limited
+ size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't
+ use recursion in the match() function; instead it creates its own stack by
+ steam using memory from the heap. For more detail, see the comments and
+ other stuff just above the match() function. */
+/* #undef HEAP_MATCH_RECURSE */
+
+/* The value of LINK_SIZE determines the number of bytes used to store links
+ as offsets within the compiled regex. The default is 2, which allows for
+ compiled patterns up to 64K long. This covers the vast majority of cases.
+ However, PCRE2 can also be compiled to use 3 or 4 bytes instead. This
+ allows for longer patterns in extreme cases. */
+#ifndef LINK_SIZE
+#define LINK_SIZE 2
+#endif
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* This is ignored unless you are using libtool. */
+#ifndef LT_OBJDIR
+#define LT_OBJDIR ".libs/"
+#endif
+
+/* The value of MATCH_LIMIT determines the default number of times the
+ internal match() function can be called during a single execution of
+ pcre2_match(). There is a runtime interface for setting a different limit.
+ The limit exists in order to catch runaway regular expressions that take
+ for ever to determine that they do not match. The default is set very large
+ so that it does not accidentally catch legitimate cases. */
+#ifndef MATCH_LIMIT
+#define MATCH_LIMIT 10000000
+#endif
+
+/* The above limit applies to all calls of match(), whether or not they
+ increase the recursion depth. In some environments it is desirable to limit
+ the depth of recursive calls of match() more strictly, in order to restrict
+ the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined)
+ that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive
+ calls of match(). To have any useful effect, it must be less than the value
+ of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There
+ is a runtime method for setting a different limit. */
+#ifndef MATCH_LIMIT_RECURSION
+#define MATCH_LIMIT_RECURSION MATCH_LIMIT
+#endif
+
+/* This limit is parameterized just in case anybody ever wants to change it.
+ Care must be taken if it is increased, because it guards against integer
+ overflow caused by enormously large patterns. */
+#ifndef MAX_NAME_COUNT
+#define MAX_NAME_COUNT 10000
+#endif
+
+/* This limit is parameterized just in case anybody ever wants to change it.
+ Care must be taken if it is increased, because it guards against integer
+ overflow caused by enormously large patterns. */
+#ifndef MAX_NAME_SIZE
+#define MAX_NAME_SIZE 32
+#endif
+
+/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */
+/* #undef NEVER_BACKSLASH_C */
+
+/* The value of NEWLINE_DEFAULT determines the default newline character
+ sequence. PCRE2 client programs can override this by selecting other values
+ at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), and 5
+ (ANYCRLF). */
+#ifndef NEWLINE_DEFAULT
+#define NEWLINE_DEFAULT 2
+#endif
+
+/* Name of package */
+#define PACKAGE "pcre2"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "PCRE2"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "PCRE2 10.23"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "pcre2"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "10.23"
+
+/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
+ parentheses (of any kind) in a pattern. This limits the amount of system
+ stack that is used while compiling a pattern. */
+#ifndef PARENS_NEST_LIMIT
+#define PARENS_NEST_LIMIT 250
+#endif
+
+/* The value of PCRE2GREP_BUFSIZE is the starting size of the buffer used by
+ pcre2grep to hold parts of the file it is searching. The buffer will be
+ expanded up to PCRE2GREP_MAX_BUFSIZE if necessary, for files containing
+ very long lines. The actual amount of memory used by pcre2grep is three
+ times this number, because it allows for the buffering of "before" and
+ "after" lines. */
+#ifndef PCRE2GREP_BUFSIZE
+#define PCRE2GREP_BUFSIZE 20480
+#endif
+
+/* The value of PCRE2GREP_MAX_BUFSIZE specifies the maximum size of the buffer
+ used by pcre2grep to hold parts of the file it is searching. The actual
+ amount of memory used by pcre2grep is three times this number, because it
+ allows for the buffering of "before" and "after" lines. */
+#ifndef PCRE2GREP_MAX_BUFSIZE
+#define PCRE2GREP_MAX_BUFSIZE 1048576
+#endif
+
+/* Define to any value to include debugging code. */
+/* #undef PCRE2_DEBUG */
+
+/* If you are compiling for a system other than a Unix-like system or
+ Win32, and it needs some magic to be inserted before the definition
+ of a function that is exported by the library, define this macro to
+ contain the relevant magic. If you do not define this macro, a suitable
+ __declspec value is used for Windows systems; in other environments
+ "extern" is used for a C compiler and "extern C" for a C++ compiler.
+ This macro apears at the start of every exported function that is part
+ of the external API. It does not appear on functions that are "external"
+ in the C sense, but which are internal to the library. */
+/* #undef PCRE2_EXP_DEFN */
+
+/* Define to any value if linking statically (TODO: make nice with Libtool) */
+/* #undef PCRE2_STATIC */
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+/* #undef STDC_HEADERS */
+
+/* Define to any value to enable support for Just-In-Time compiling. */
+/* #undef SUPPORT_JIT */
+
+/* Define to any value to allow pcre2grep to be linked with libbz2, so that it
+ is able to handle .bz2 files. */
+/* #undef SUPPORT_LIBBZ2 */
+
+/* Define to any value to allow pcre2test to be linked with libedit. */
+/* #undef SUPPORT_LIBEDIT */
+
+/* Define to any value to allow pcre2test to be linked with libreadline. */
+/* #undef SUPPORT_LIBREADLINE */
+
+/* Define to any value to allow pcre2grep to be linked with libz, so that it
+ is able to handle .gz files. */
+/* #undef SUPPORT_LIBZ */
+
+/* Define to any value to enable callout script support in pcre2grep. */
+/* #undef SUPPORT_PCRE2GREP_CALLOUT */
+
+/* Define to any value to enable JIT support in pcre2grep. Note that this will
+ have no effect unless SUPPORT_JIT is also defined. */
+/* #undef SUPPORT_PCRE2GREP_JIT */
+
+/* Define to any value to enable the 16 bit PCRE2 library. */
+/* #undef SUPPORT_PCRE2_16 */
+
+/* Define to any value to enable the 32 bit PCRE2 library. */
+/* #undef SUPPORT_PCRE2_32 */
+
+/* Define to any value to enable the 8 bit PCRE2 library. */
+/* #undef SUPPORT_PCRE2_8 */
+
+/* Define to any value to enable support for Unicode and UTF encoding. This
+ will work even in an EBCDIC environment, but it is incompatible with the
+ EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or*
+ ASCII/Unicode, but not both at once. */
+/* #undef SUPPORT_UNICODE */
+
+/* Define to any value for valgrind support to find invalid memory reads. */
+/* #undef SUPPORT_VALGRIND */
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+/* Version number of package */
+#define VERSION "10.23"
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+/* #undef int64_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/thirdparty/pcre2/src/pcre2.h b/thirdparty/pcre2/src/pcre2.h
new file mode 100644
index 0000000000..86503208e8
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2.h
@@ -0,0 +1,771 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* This is the public header file for the PCRE library, second API, to be
+#included by applications that call PCRE2 functions.
+
+ Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef PCRE2_H_IDEMPOTENT_GUARD
+#define PCRE2_H_IDEMPOTENT_GUARD
+
+/* The current PCRE version information. */
+
+#define PCRE2_MAJOR 10
+#define PCRE2_MINOR 23
+#define PCRE2_PRERELEASE
+#define PCRE2_DATE 2017-02-14
+
+/* When an application links to a PCRE DLL in Windows, the symbols that are
+imported have to be identified as such. When building PCRE2, the appropriate
+export setting is defined in pcre2_internal.h, which includes this file. So we
+don't change existing definitions of PCRE2_EXP_DECL. */
+
+#if defined(_WIN32) && !defined(PCRE2_STATIC)
+# ifndef PCRE2_EXP_DECL
+# define PCRE2_EXP_DECL extern __declspec(dllimport)
+# endif
+#endif
+
+/* By default, we use the standard "extern" declarations. */
+
+#ifndef PCRE2_EXP_DECL
+# ifdef __cplusplus
+# define PCRE2_EXP_DECL extern "C"
+# else
+# define PCRE2_EXP_DECL extern
+# endif
+#endif
+
+/* When compiling with the MSVC compiler, it is sometimes necessary to include
+a "calling convention" before exported function names. (This is secondhand
+information; I know nothing about MSVC myself). For example, something like
+
+ void __cdecl function(....)
+
+might be needed. In order so make this easy, all the exported functions have
+PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not
+set, we ensure here that it has no effect. */
+
+#ifndef PCRE2_CALL_CONVENTION
+#define PCRE2_CALL_CONVENTION
+#endif
+
+/* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and
+uint8_t, UCHAR_MAX, etc are defined. */
+
+#include <limits.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+/* Allow for C++ users compiling this directly. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following option bits can be passed to pcre2_compile(), pcre2_match(),
+or pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it
+is passed. Put these bits at the most significant end of the options word so
+others can be added next to them */
+
+#define PCRE2_ANCHORED 0x80000000u
+#define PCRE2_NO_UTF_CHECK 0x40000000u
+
+/* The following option bits can be passed only to pcre2_compile(). However,
+they may affect compilation, JIT compilation, and/or interpretive execution.
+The following tags indicate which:
+
+C alters what is compiled by pcre2_compile()
+J alters what is compiled by pcre2_jit_compile()
+M is inspected during pcre2_match() execution
+D is inspected during pcre2_dfa_match() execution
+*/
+
+#define PCRE2_ALLOW_EMPTY_CLASS 0x00000001u /* C */
+#define PCRE2_ALT_BSUX 0x00000002u /* C */
+#define PCRE2_AUTO_CALLOUT 0x00000004u /* C */
+#define PCRE2_CASELESS 0x00000008u /* C */
+#define PCRE2_DOLLAR_ENDONLY 0x00000010u /* J M D */
+#define PCRE2_DOTALL 0x00000020u /* C */
+#define PCRE2_DUPNAMES 0x00000040u /* C */
+#define PCRE2_EXTENDED 0x00000080u /* C */
+#define PCRE2_FIRSTLINE 0x00000100u /* J M D */
+#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u /* C J M */
+#define PCRE2_MULTILINE 0x00000400u /* C */
+#define PCRE2_NEVER_UCP 0x00000800u /* C */
+#define PCRE2_NEVER_UTF 0x00001000u /* C */
+#define PCRE2_NO_AUTO_CAPTURE 0x00002000u /* C */
+#define PCRE2_NO_AUTO_POSSESS 0x00004000u /* C */
+#define PCRE2_NO_DOTSTAR_ANCHOR 0x00008000u /* C */
+#define PCRE2_NO_START_OPTIMIZE 0x00010000u /* J M D */
+#define PCRE2_UCP 0x00020000u /* C J M D */
+#define PCRE2_UNGREEDY 0x00040000u /* C */
+#define PCRE2_UTF 0x00080000u /* C J M D */
+#define PCRE2_NEVER_BACKSLASH_C 0x00100000u /* C */
+#define PCRE2_ALT_CIRCUMFLEX 0x00200000u /* J M D */
+#define PCRE2_ALT_VERBNAMES 0x00400000u /* C */
+#define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */
+
+/* These are for pcre2_jit_compile(). */
+
+#define PCRE2_JIT_COMPLETE 0x00000001u /* For full matching */
+#define PCRE2_JIT_PARTIAL_SOFT 0x00000002u
+#define PCRE2_JIT_PARTIAL_HARD 0x00000004u
+
+/* These are for pcre2_match(), pcre2_dfa_match(), and pcre2_jit_match(). Note
+that PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK can also be passed to these
+functions (though pcre2_jit_match() ignores the latter since it bypasses all
+sanity checks). */
+
+#define PCRE2_NOTBOL 0x00000001u
+#define PCRE2_NOTEOL 0x00000002u
+#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */
+#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */
+#define PCRE2_PARTIAL_SOFT 0x00000010u
+#define PCRE2_PARTIAL_HARD 0x00000020u
+
+/* These are additional options for pcre2_dfa_match(). */
+
+#define PCRE2_DFA_RESTART 0x00000040u
+#define PCRE2_DFA_SHORTEST 0x00000080u
+
+/* These are additional options for pcre2_substitute(), which passes any others
+through to pcre2_match(). */
+
+#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u
+#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u
+#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u
+#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u
+#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u
+
+/* A further option for pcre2_match(), not allowed for pcre2_dfa_match(),
+ignored for pcre2_jit_match(). */
+
+#define PCRE2_NO_JIT 0x00002000u
+
+/* Newline and \R settings, for use in compile contexts. The newline values
+must be kept in step with values set in config.h and both sets must all be
+greater than zero. */
+
+#define PCRE2_NEWLINE_CR 1
+#define PCRE2_NEWLINE_LF 2
+#define PCRE2_NEWLINE_CRLF 3
+#define PCRE2_NEWLINE_ANY 4
+#define PCRE2_NEWLINE_ANYCRLF 5
+
+#define PCRE2_BSR_UNICODE 1
+#define PCRE2_BSR_ANYCRLF 2
+
+/* Error codes: no match and partial match are "expected" errors. */
+
+#define PCRE2_ERROR_NOMATCH (-1)
+#define PCRE2_ERROR_PARTIAL (-2)
+
+/* Error codes for UTF-8 validity checks */
+
+#define PCRE2_ERROR_UTF8_ERR1 (-3)
+#define PCRE2_ERROR_UTF8_ERR2 (-4)
+#define PCRE2_ERROR_UTF8_ERR3 (-5)
+#define PCRE2_ERROR_UTF8_ERR4 (-6)
+#define PCRE2_ERROR_UTF8_ERR5 (-7)
+#define PCRE2_ERROR_UTF8_ERR6 (-8)
+#define PCRE2_ERROR_UTF8_ERR7 (-9)
+#define PCRE2_ERROR_UTF8_ERR8 (-10)
+#define PCRE2_ERROR_UTF8_ERR9 (-11)
+#define PCRE2_ERROR_UTF8_ERR10 (-12)
+#define PCRE2_ERROR_UTF8_ERR11 (-13)
+#define PCRE2_ERROR_UTF8_ERR12 (-14)
+#define PCRE2_ERROR_UTF8_ERR13 (-15)
+#define PCRE2_ERROR_UTF8_ERR14 (-16)
+#define PCRE2_ERROR_UTF8_ERR15 (-17)
+#define PCRE2_ERROR_UTF8_ERR16 (-18)
+#define PCRE2_ERROR_UTF8_ERR17 (-19)
+#define PCRE2_ERROR_UTF8_ERR18 (-20)
+#define PCRE2_ERROR_UTF8_ERR19 (-21)
+#define PCRE2_ERROR_UTF8_ERR20 (-22)
+#define PCRE2_ERROR_UTF8_ERR21 (-23)
+
+/* Error codes for UTF-16 validity checks */
+
+#define PCRE2_ERROR_UTF16_ERR1 (-24)
+#define PCRE2_ERROR_UTF16_ERR2 (-25)
+#define PCRE2_ERROR_UTF16_ERR3 (-26)
+
+/* Error codes for UTF-32 validity checks */
+
+#define PCRE2_ERROR_UTF32_ERR1 (-27)
+#define PCRE2_ERROR_UTF32_ERR2 (-28)
+
+/* Error codes for pcre2[_dfa]_match(), substring extraction functions, context
+functions, and serializing functions. They are in numerical order. Originally
+they were in alphabetical order too, but now that PCRE2 is released, the
+numbers must not be changed. */
+
+#define PCRE2_ERROR_BADDATA (-29)
+#define PCRE2_ERROR_MIXEDTABLES (-30) /* Name was changed */
+#define PCRE2_ERROR_BADMAGIC (-31)
+#define PCRE2_ERROR_BADMODE (-32)
+#define PCRE2_ERROR_BADOFFSET (-33)
+#define PCRE2_ERROR_BADOPTION (-34)
+#define PCRE2_ERROR_BADREPLACEMENT (-35)
+#define PCRE2_ERROR_BADUTFOFFSET (-36)
+#define PCRE2_ERROR_CALLOUT (-37) /* Never used by PCRE2 itself */
+#define PCRE2_ERROR_DFA_BADRESTART (-38)
+#define PCRE2_ERROR_DFA_RECURSE (-39)
+#define PCRE2_ERROR_DFA_UCOND (-40)
+#define PCRE2_ERROR_DFA_UFUNC (-41)
+#define PCRE2_ERROR_DFA_UITEM (-42)
+#define PCRE2_ERROR_DFA_WSSIZE (-43)
+#define PCRE2_ERROR_INTERNAL (-44)
+#define PCRE2_ERROR_JIT_BADOPTION (-45)
+#define PCRE2_ERROR_JIT_STACKLIMIT (-46)
+#define PCRE2_ERROR_MATCHLIMIT (-47)
+#define PCRE2_ERROR_NOMEMORY (-48)
+#define PCRE2_ERROR_NOSUBSTRING (-49)
+#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)
+#define PCRE2_ERROR_NULL (-51)
+#define PCRE2_ERROR_RECURSELOOP (-52)
+#define PCRE2_ERROR_RECURSIONLIMIT (-53)
+#define PCRE2_ERROR_UNAVAILABLE (-54)
+#define PCRE2_ERROR_UNSET (-55)
+#define PCRE2_ERROR_BADOFFSETLIMIT (-56)
+#define PCRE2_ERROR_BADREPESCAPE (-57)
+#define PCRE2_ERROR_REPMISSINGBRACE (-58)
+#define PCRE2_ERROR_BADSUBSTITUTION (-59)
+#define PCRE2_ERROR_BADSUBSPATTERN (-60)
+#define PCRE2_ERROR_TOOMANYREPLACE (-61)
+#define PCRE2_ERROR_BADSERIALIZEDDATA (-62)
+
+/* Request types for pcre2_pattern_info() */
+
+#define PCRE2_INFO_ALLOPTIONS 0
+#define PCRE2_INFO_ARGOPTIONS 1
+#define PCRE2_INFO_BACKREFMAX 2
+#define PCRE2_INFO_BSR 3
+#define PCRE2_INFO_CAPTURECOUNT 4
+#define PCRE2_INFO_FIRSTCODEUNIT 5
+#define PCRE2_INFO_FIRSTCODETYPE 6
+#define PCRE2_INFO_FIRSTBITMAP 7
+#define PCRE2_INFO_HASCRORLF 8
+#define PCRE2_INFO_JCHANGED 9
+#define PCRE2_INFO_JITSIZE 10
+#define PCRE2_INFO_LASTCODEUNIT 11
+#define PCRE2_INFO_LASTCODETYPE 12
+#define PCRE2_INFO_MATCHEMPTY 13
+#define PCRE2_INFO_MATCHLIMIT 14
+#define PCRE2_INFO_MAXLOOKBEHIND 15
+#define PCRE2_INFO_MINLENGTH 16
+#define PCRE2_INFO_NAMECOUNT 17
+#define PCRE2_INFO_NAMEENTRYSIZE 18
+#define PCRE2_INFO_NAMETABLE 19
+#define PCRE2_INFO_NEWLINE 20
+#define PCRE2_INFO_RECURSIONLIMIT 21
+#define PCRE2_INFO_SIZE 22
+#define PCRE2_INFO_HASBACKSLASHC 23
+
+/* Request types for pcre2_config(). */
+
+#define PCRE2_CONFIG_BSR 0
+#define PCRE2_CONFIG_JIT 1
+#define PCRE2_CONFIG_JITTARGET 2
+#define PCRE2_CONFIG_LINKSIZE 3
+#define PCRE2_CONFIG_MATCHLIMIT 4
+#define PCRE2_CONFIG_NEWLINE 5
+#define PCRE2_CONFIG_PARENSLIMIT 6
+#define PCRE2_CONFIG_RECURSIONLIMIT 7
+#define PCRE2_CONFIG_STACKRECURSE 8
+#define PCRE2_CONFIG_UNICODE 9
+#define PCRE2_CONFIG_UNICODE_VERSION 10
+#define PCRE2_CONFIG_VERSION 11
+
+/* Types for code units in patterns and subject strings. */
+
+typedef uint8_t PCRE2_UCHAR8;
+typedef uint16_t PCRE2_UCHAR16;
+typedef uint32_t PCRE2_UCHAR32;
+
+typedef const PCRE2_UCHAR8 *PCRE2_SPTR8;
+typedef const PCRE2_UCHAR16 *PCRE2_SPTR16;
+typedef const PCRE2_UCHAR32 *PCRE2_SPTR32;
+
+/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2,
+including pattern offsets for errors and subject offsets after a match. We
+define special values to indicate zero-terminated strings and unset offsets in
+the offset vector (ovector). */
+
+#define PCRE2_SIZE size_t
+#define PCRE2_SIZE_MAX SIZE_MAX
+#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)
+#define PCRE2_UNSET (~(PCRE2_SIZE)0)
+
+/* Generic types for opaque structures and JIT callback functions. These
+declarations are defined in a macro that is expanded for each width later. */
+
+#define PCRE2_TYPES_LIST \
+struct pcre2_real_general_context; \
+typedef struct pcre2_real_general_context pcre2_general_context; \
+\
+struct pcre2_real_compile_context; \
+typedef struct pcre2_real_compile_context pcre2_compile_context; \
+\
+struct pcre2_real_match_context; \
+typedef struct pcre2_real_match_context pcre2_match_context; \
+\
+struct pcre2_real_code; \
+typedef struct pcre2_real_code pcre2_code; \
+\
+struct pcre2_real_match_data; \
+typedef struct pcre2_real_match_data pcre2_match_data; \
+\
+struct pcre2_real_jit_stack; \
+typedef struct pcre2_real_jit_stack pcre2_jit_stack; \
+\
+typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *);
+
+
+/* The structure for passing out data via the pcre_callout_function. We use a
+structure so that new fields can be added on the end in future versions,
+without changing the API of the function, thereby allowing old clients to work
+without modification. Define the generic version in a macro; the width-specific
+versions are generated from this macro below. */
+
+#define PCRE2_STRUCTURE_LIST \
+typedef struct pcre2_callout_block { \
+ uint32_t version; /* Identifies version of block */ \
+ /* ------------------------ Version 0 ------------------------------- */ \
+ uint32_t callout_number; /* Number compiled into pattern */ \
+ uint32_t capture_top; /* Max current capture */ \
+ uint32_t capture_last; /* Most recently closed capture */ \
+ PCRE2_SIZE *offset_vector; /* The offset vector */ \
+ PCRE2_SPTR mark; /* Pointer to current mark or NULL */ \
+ PCRE2_SPTR subject; /* The subject being matched */ \
+ PCRE2_SIZE subject_length; /* The length of the subject */ \
+ PCRE2_SIZE start_match; /* Offset to start of this match attempt */ \
+ PCRE2_SIZE current_position; /* Where we currently are in the subject */ \
+ PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \
+ PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \
+ /* ------------------- Added for Version 1 -------------------------- */ \
+ PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \
+ PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \
+ PCRE2_SPTR callout_string; /* String compiled into pattern */ \
+ /* ------------------------------------------------------------------ */ \
+} pcre2_callout_block; \
+\
+typedef struct pcre2_callout_enumerate_block { \
+ uint32_t version; /* Identifies version of block */ \
+ /* ------------------------ Version 0 ------------------------------- */ \
+ PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \
+ PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \
+ uint32_t callout_number; /* Number compiled into pattern */ \
+ PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \
+ PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \
+ PCRE2_SPTR callout_string; /* String compiled into pattern */ \
+ /* ------------------------------------------------------------------ */ \
+} pcre2_callout_enumerate_block;
+
+
+/* List the generic forms of all other functions in macros, which will be
+expanded for each width below. Start with functions that give general
+information. */
+
+#define PCRE2_GENERAL_INFO_FUNCTIONS \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *);
+
+
+/* Functions for manipulating contexts. */
+
+#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \
+PCRE2_EXP_DECL pcre2_general_context PCRE2_CALL_CONVENTION \
+ *pcre2_general_context_copy(pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_general_context PCRE2_CALL_CONVENTION \
+ *pcre2_general_context_create(void *(*)(PCRE2_SIZE, void *), \
+ void (*)(void *, void *), void *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_general_context_free(pcre2_general_context *);
+
+#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \
+PCRE2_EXP_DECL pcre2_compile_context PCRE2_CALL_CONVENTION \
+ *pcre2_compile_context_copy(pcre2_compile_context *); \
+PCRE2_EXP_DECL pcre2_compile_context PCRE2_CALL_CONVENTION \
+ *pcre2_compile_context_create(pcre2_general_context *);\
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_compile_context_free(pcre2_compile_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_bsr(pcre2_compile_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_character_tables(pcre2_compile_context *, const unsigned char *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_newline(pcre2_compile_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_parens_nest_limit(pcre2_compile_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_compile_recursion_guard(pcre2_compile_context *, \
+ int (*)(uint32_t, void *), void *);
+
+#define PCRE2_MATCH_CONTEXT_FUNCTIONS \
+PCRE2_EXP_DECL pcre2_match_context PCRE2_CALL_CONVENTION \
+ *pcre2_match_context_copy(pcre2_match_context *); \
+PCRE2_EXP_DECL pcre2_match_context PCRE2_CALL_CONVENTION \
+ *pcre2_match_context_create(pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_match_context_free(pcre2_match_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_callout(pcre2_match_context *, \
+ int (*)(pcre2_callout_block *, void *), void *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_match_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_set_recursion_memory_management(pcre2_match_context *, \
+ void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *);
+
+
+/* Functions concerned with compiling a pattern to PCRE internal code. */
+
+#define PCRE2_COMPILE_FUNCTIONS \
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+ *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, \
+ pcre2_compile_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_code_free(pcre2_code *); \
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+ *pcre2_code_copy(const pcre2_code *); \
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+ *pcre2_code_copy_with_tables(const pcre2_code *);
+
+
+/* Functions that give information about a compiled pattern. */
+
+#define PCRE2_PATTERN_INFO_FUNCTIONS \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_pattern_info(const pcre2_code *, uint32_t, void *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_callout_enumerate(const pcre2_code *, \
+ int (*)(pcre2_callout_enumerate_block *, void *), void *);
+
+
+/* Functions for running a match and inspecting the result. */
+
+#define PCRE2_MATCH_FUNCTIONS \
+PCRE2_EXP_DECL pcre2_match_data PCRE2_CALL_CONVENTION \
+ *pcre2_match_data_create(uint32_t, pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_match_data PCRE2_CALL_CONVENTION \
+ *pcre2_match_data_create_from_pattern(const pcre2_code *, \
+ pcre2_general_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+ uint32_t, pcre2_match_data *, pcre2_match_context *, int *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+ uint32_t, pcre2_match_data *, pcre2_match_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_match_data_free(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \
+ pcre2_get_mark(pcre2_match_data *); \
+PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \
+ pcre2_get_ovector_count(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
+ *pcre2_get_ovector_pointer(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
+ pcre2_get_startchar(pcre2_match_data *);
+
+
+/* Convenience functions for handling matched substrings. */
+
+#define PCRE2_SUBSTRING_FUNCTIONS \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_copy_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR *, \
+ PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_copy_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR *, \
+ PCRE2_SIZE *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_substring_free(PCRE2_UCHAR *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_get_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR **, \
+ PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_get_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR **, \
+ PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_length_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_length_bynumber(pcre2_match_data *, uint32_t, PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_nametable_scan(const pcre2_code *, PCRE2_SPTR, PCRE2_SPTR *, \
+ PCRE2_SPTR *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_substring_list_free(PCRE2_SPTR *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **);
+
+/* Functions for serializing / deserializing compiled patterns. */
+
+#define PCRE2_SERIALIZE_FUNCTIONS \
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+ pcre2_serialize_encode(const pcre2_code **, int32_t, uint8_t **, \
+ PCRE2_SIZE *, pcre2_general_context *); \
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+ pcre2_serialize_decode(pcre2_code **, int32_t, const uint8_t *, \
+ pcre2_general_context *); \
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+ pcre2_serialize_get_number_of_codes(const uint8_t *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_serialize_free(uint8_t *);
+
+
+/* Convenience function for match + substitute. */
+
+#define PCRE2_SUBSTITUTE_FUNCTION \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_substitute(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+ uint32_t, pcre2_match_data *, pcre2_match_context *, PCRE2_SPTR, \
+ PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE *);
+
+
+/* Functions for JIT processing */
+
+#define PCRE2_JIT_FUNCTIONS \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_jit_compile(pcre2_code *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_jit_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+ uint32_t, pcre2_match_data *, pcre2_match_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_jit_free_unused_memory(pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_jit_stack PCRE2_CALL_CONVENTION \
+ *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_jit_stack_free(pcre2_jit_stack *);
+
+
+/* Other miscellaneous functions. */
+
+#define PCRE2_OTHER_FUNCTIONS \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \
+PCRE2_EXP_DECL const uint8_t PCRE2_CALL_CONVENTION \
+ *pcre2_maketables(pcre2_general_context *); \
+
+
+/* Define macros that generate width-specific names from generic versions. The
+three-level macro scheme is necessary to get the macros expanded when we want
+them to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for
+generating three versions of everything below. After that, PCRE2_SUFFIX will be
+re-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as
+pcre2_compile are called by application code. */
+
+#define PCRE2_JOIN(a,b) a ## b
+#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b)
+#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH)
+
+
+/* Data types */
+
+#define PCRE2_UCHAR PCRE2_SUFFIX(PCRE2_UCHAR)
+#define PCRE2_SPTR PCRE2_SUFFIX(PCRE2_SPTR)
+
+#define pcre2_code PCRE2_SUFFIX(pcre2_code_)
+#define pcre2_jit_callback PCRE2_SUFFIX(pcre2_jit_callback_)
+#define pcre2_jit_stack PCRE2_SUFFIX(pcre2_jit_stack_)
+
+#define pcre2_real_code PCRE2_SUFFIX(pcre2_real_code_)
+#define pcre2_real_general_context PCRE2_SUFFIX(pcre2_real_general_context_)
+#define pcre2_real_compile_context PCRE2_SUFFIX(pcre2_real_compile_context_)
+#define pcre2_real_match_context PCRE2_SUFFIX(pcre2_real_match_context_)
+#define pcre2_real_jit_stack PCRE2_SUFFIX(pcre2_real_jit_stack_)
+#define pcre2_real_match_data PCRE2_SUFFIX(pcre2_real_match_data_)
+
+
+/* Data blocks */
+
+#define pcre2_callout_block PCRE2_SUFFIX(pcre2_callout_block_)
+#define pcre2_callout_enumerate_block PCRE2_SUFFIX(pcre2_callout_enumerate_block_)
+#define pcre2_general_context PCRE2_SUFFIX(pcre2_general_context_)
+#define pcre2_compile_context PCRE2_SUFFIX(pcre2_compile_context_)
+#define pcre2_match_context PCRE2_SUFFIX(pcre2_match_context_)
+#define pcre2_match_data PCRE2_SUFFIX(pcre2_match_data_)
+
+
+/* Functions: the complete list in alphabetical order */
+
+#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_)
+#define pcre2_code_copy PCRE2_SUFFIX(pcre2_code_copy_)
+#define pcre2_code_copy_with_tables PCRE2_SUFFIX(pcre2_code_copy_with_tables_)
+#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_)
+#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_)
+#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_)
+#define pcre2_compile_context_create PCRE2_SUFFIX(pcre2_compile_context_create_)
+#define pcre2_compile_context_free PCRE2_SUFFIX(pcre2_compile_context_free_)
+#define pcre2_config PCRE2_SUFFIX(pcre2_config_)
+#define pcre2_dfa_match PCRE2_SUFFIX(pcre2_dfa_match_)
+#define pcre2_general_context_copy PCRE2_SUFFIX(pcre2_general_context_copy_)
+#define pcre2_general_context_create PCRE2_SUFFIX(pcre2_general_context_create_)
+#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_)
+#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_)
+#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_)
+#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_)
+#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_)
+#define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_)
+#define pcre2_jit_compile PCRE2_SUFFIX(pcre2_jit_compile_)
+#define pcre2_jit_match PCRE2_SUFFIX(pcre2_jit_match_)
+#define pcre2_jit_free_unused_memory PCRE2_SUFFIX(pcre2_jit_free_unused_memory_)
+#define pcre2_jit_stack_assign PCRE2_SUFFIX(pcre2_jit_stack_assign_)
+#define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_)
+#define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_)
+#define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_)
+#define pcre2_match PCRE2_SUFFIX(pcre2_match_)
+#define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_)
+#define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_)
+#define pcre2_match_context_free PCRE2_SUFFIX(pcre2_match_context_free_)
+#define pcre2_match_data_create PCRE2_SUFFIX(pcre2_match_data_create_)
+#define pcre2_match_data_create_from_pattern PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_)
+#define pcre2_match_data_free PCRE2_SUFFIX(pcre2_match_data_free_)
+#define pcre2_pattern_info PCRE2_SUFFIX(pcre2_pattern_info_)
+#define pcre2_serialize_decode PCRE2_SUFFIX(pcre2_serialize_decode_)
+#define pcre2_serialize_encode PCRE2_SUFFIX(pcre2_serialize_encode_)
+#define pcre2_serialize_free PCRE2_SUFFIX(pcre2_serialize_free_)
+#define pcre2_serialize_get_number_of_codes PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_)
+#define pcre2_set_bsr PCRE2_SUFFIX(pcre2_set_bsr_)
+#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_)
+#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_)
+#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)
+#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_)
+#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_)
+#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_)
+#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)
+#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_)
+#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)
+#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
+#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_)
+#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_)
+#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_)
+#define pcre2_substring_free PCRE2_SUFFIX(pcre2_substring_free_)
+#define pcre2_substring_get_byname PCRE2_SUFFIX(pcre2_substring_get_byname_)
+#define pcre2_substring_get_bynumber PCRE2_SUFFIX(pcre2_substring_get_bynumber_)
+#define pcre2_substring_length_byname PCRE2_SUFFIX(pcre2_substring_length_byname_)
+#define pcre2_substring_length_bynumber PCRE2_SUFFIX(pcre2_substring_length_bynumber_)
+#define pcre2_substring_list_get PCRE2_SUFFIX(pcre2_substring_list_get_)
+#define pcre2_substring_list_free PCRE2_SUFFIX(pcre2_substring_list_free_)
+#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_)
+#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_)
+
+
+/* Now generate all three sets of width-specific structures and function
+prototypes. */
+
+#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \
+PCRE2_TYPES_LIST \
+PCRE2_STRUCTURE_LIST \
+PCRE2_GENERAL_INFO_FUNCTIONS \
+PCRE2_GENERAL_CONTEXT_FUNCTIONS \
+PCRE2_COMPILE_CONTEXT_FUNCTIONS \
+PCRE2_MATCH_CONTEXT_FUNCTIONS \
+PCRE2_COMPILE_FUNCTIONS \
+PCRE2_PATTERN_INFO_FUNCTIONS \
+PCRE2_MATCH_FUNCTIONS \
+PCRE2_SUBSTRING_FUNCTIONS \
+PCRE2_SERIALIZE_FUNCTIONS \
+PCRE2_SUBSTITUTE_FUNCTION \
+PCRE2_JIT_FUNCTIONS \
+PCRE2_OTHER_FUNCTIONS
+
+#define PCRE2_LOCAL_WIDTH 8
+PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
+#undef PCRE2_LOCAL_WIDTH
+
+#define PCRE2_LOCAL_WIDTH 16
+PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
+#undef PCRE2_LOCAL_WIDTH
+
+#define PCRE2_LOCAL_WIDTH 32
+PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
+#undef PCRE2_LOCAL_WIDTH
+
+/* Undefine the list macros; they are no longer needed. */
+
+#undef PCRE2_TYPES_LIST
+#undef PCRE2_STRUCTURE_LIST
+#undef PCRE2_GENERAL_INFO_FUNCTIONS
+#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS
+#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS
+#undef PCRE2_MATCH_CONTEXT_FUNCTIONS
+#undef PCRE2_COMPILE_FUNCTIONS
+#undef PCRE2_PATTERN_INFO_FUNCTIONS
+#undef PCRE2_MATCH_FUNCTIONS
+#undef PCRE2_SUBSTRING_FUNCTIONS
+#undef PCRE2_SERIALIZE_FUNCTIONS
+#undef PCRE2_SUBSTITUTE_FUNCTION
+#undef PCRE2_JIT_FUNCTIONS
+#undef PCRE2_OTHER_FUNCTIONS
+#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
+
+/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine
+PCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make
+PCRE2_SUFFIX a no-op. Otherwise, generate an error. */
+
+#undef PCRE2_SUFFIX
+#ifndef PCRE2_CODE_UNIT_WIDTH
+#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h.
+#error Use 8, 16, or 32; or 0 for a multi-width application.
+#else /* PCRE2_CODE_UNIT_WIDTH is defined */
+#if PCRE2_CODE_UNIT_WIDTH == 8 || \
+ PCRE2_CODE_UNIT_WIDTH == 16 || \
+ PCRE2_CODE_UNIT_WIDTH == 32
+#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH)
+#elif PCRE2_CODE_UNIT_WIDTH == 0
+#undef PCRE2_JOIN
+#undef PCRE2_GLUE
+#define PCRE2_SUFFIX(a) a
+#else
+#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32.
+#endif
+#endif /* PCRE2_CODE_UNIT_WIDTH is defined */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PCRE2_H_IDEMPOTENT_GUARD */
+
+/* End of pcre2.h */
diff --git a/thirdparty/pcre2/src/pcre2_auto_possess.c b/thirdparty/pcre2/src/pcre2_auto_possess.c
new file mode 100644
index 0000000000..64ec6dfbbc
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_auto_possess.c
@@ -0,0 +1,1293 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This module contains functions that scan a compiled pattern and change
+repeats into possessive repeats where possible. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "pcre2_internal.h"
+
+
+/*************************************************
+* Tables for auto-possessification *
+*************************************************/
+
+/* This table is used to check whether auto-possessification is possible
+between adjacent character-type opcodes. The left-hand (repeated) opcode is
+used to select the row, and the right-hand opcode is use to select the column.
+A value of 1 means that auto-possessification is OK. For example, the second
+value in the first row means that \D+\d can be turned into \D++\d.
+
+The Unicode property types (\P and \p) have to be present to fill out the table
+because of what their opcode values are, but the table values should always be
+zero because property types are handled separately in the code. The last four
+columns apply to items that cannot be repeated, so there is no need to have
+rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is
+*not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
+
+#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1)
+#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1)
+
+static const uint8_t autoposstab[APTROWS][APTCOLS] = {
+/* \D \d \S \s \W \w . .+ \C \P \p \R \H \h \V \v \X \Z \z $ $M */
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \D */
+ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \d */
+ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \S */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \s */
+ { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \W */
+ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \w */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* . */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* .+ */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \C */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \P */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \p */
+ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \R */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \H */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \h */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \V */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, /* \v */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */
+};
+
+#ifdef SUPPORT_UNICODE
+/* This table is used to check whether auto-possessification is possible
+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The
+left-hand (repeated) opcode is used to select the row, and the right-hand
+opcode is used to select the column. The values are as follows:
+
+ 0 Always return FALSE (never auto-possessify)
+ 1 Character groups are distinct (possessify if both are OP_PROP)
+ 2 Check character categories in the same group (general or particular)
+ 3 TRUE if the two opcodes are not the same (PROP vs NOTPROP)
+
+ 4 Check left general category vs right particular category
+ 5 Check right general category vs left particular category
+
+ 6 Left alphanum vs right general category
+ 7 Left space vs right general category
+ 8 Left word vs right general category
+
+ 9 Right alphanum vs left general category
+ 10 Right space vs left general category
+ 11 Right word vs left general category
+
+ 12 Left alphanum vs right particular category
+ 13 Left space vs right particular category
+ 14 Left word vs right particular category
+
+ 15 Right alphanum vs left particular category
+ 16 Right space vs left particular category
+ 17 Right word vs left particular category
+*/
+
+static const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = {
+/* ANY LAMP GC PC SC ALNUM SPACE PXSPACE WORD CLIST UCNC */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */
+ { 0, 3, 0, 0, 0, 3, 1, 1, 0, 0, 0 }, /* PT_LAMP */
+ { 0, 0, 2, 4, 0, 9, 10, 10, 11, 0, 0 }, /* PT_GC */
+ { 0, 0, 5, 2, 0, 15, 16, 16, 17, 0, 0 }, /* PT_PC */
+ { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, /* PT_SC */
+ { 0, 3, 6, 12, 0, 3, 1, 1, 0, 0, 0 }, /* PT_ALNUM */
+ { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_SPACE */
+ { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_PXSPACE */
+ { 0, 0, 8, 14, 0, 0, 1, 1, 3, 0, 0 }, /* PT_WORD */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 } /* PT_UCNC */
+};
+
+/* This table is used to check whether auto-possessification is possible
+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one
+specifies a general category and the other specifies a particular category. The
+row is selected by the general category and the column by the particular
+category. The value is 1 if the particular category is not part of the general
+category. */
+
+static const uint8_t catposstab[7][30] = {
+/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */
+ { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* C */
+ { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* L */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* M */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* N */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, /* P */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }, /* S */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 } /* Z */
+};
+
+/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against
+a general or particular category. The properties in each row are those
+that apply to the character set in question. Duplication means that a little
+unnecessary work is done when checking, but this keeps things much simpler
+because they can all use the same code. For more details see the comment where
+this table is used.
+
+Note: SPACE and PXSPACE used to be different because Perl excluded VT from
+"space", but from Perl 5.18 it's included, so both categories are treated the
+same here. */
+
+static const uint8_t posspropstab[3][4] = {
+ { ucp_L, ucp_N, ucp_N, ucp_Nl }, /* ALNUM, 3rd and 4th values redundant */
+ { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */
+ { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */
+};
+#endif /* SUPPORT_UNICODE */
+
+
+
+#ifdef SUPPORT_UNICODE
+/*************************************************
+* Check a character and a property *
+*************************************************/
+
+/* This function is called by compare_opcodes() when a property item is
+adjacent to a fixed character.
+
+Arguments:
+ c the character
+ ptype the property type
+ pdata the data for the type
+ negated TRUE if it's a negated property (\P or \p{^)
+
+Returns: TRUE if auto-possessifying is OK
+*/
+
+static BOOL
+check_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata,
+ BOOL negated)
+{
+const uint32_t *p;
+const ucd_record *prop = GET_UCD(c);
+
+switch(ptype)
+ {
+ case PT_LAMP:
+ return (prop->chartype == ucp_Lu ||
+ prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == negated;
+
+ case PT_GC:
+ return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
+
+ case PT_PC:
+ return (pdata == prop->chartype) == negated;
+
+ case PT_SC:
+ return (pdata == prop->script) == negated;
+
+ /* These are specials */
+
+ case PT_ALNUM:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included, which
+ means that Perl space and POSIX space are now identical. PCRE was changed
+ at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ return negated;
+
+ default:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated;
+ }
+ break; /* Control never reaches here */
+
+ case PT_WORD:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == negated;
+
+ case PT_CLIST:
+ p = PRIV(ucd_caseless_sets) + prop->caseset;
+ for (;;)
+ {
+ if (c < *p) return !negated;
+ if (c == *p++) return negated;
+ }
+ break; /* Control never reaches here */
+ }
+
+return FALSE;
+}
+#endif /* SUPPORT_UNICODE */
+
+
+
+/*************************************************
+* Base opcode of repeated opcodes *
+*************************************************/
+
+/* Returns the base opcode for repeated single character type opcodes. If the
+opcode is not a repeated character type, it returns with the original value.
+
+Arguments: c opcode
+Returns: base opcode for the type
+*/
+
+static PCRE2_UCHAR
+get_repeat_base(PCRE2_UCHAR c)
+{
+return (c > OP_TYPEPOSUPTO)? c :
+ (c >= OP_TYPESTAR)? OP_TYPESTAR :
+ (c >= OP_NOTSTARI)? OP_NOTSTARI :
+ (c >= OP_NOTSTAR)? OP_NOTSTAR :
+ (c >= OP_STARI)? OP_STARI :
+ OP_STAR;
+}
+
+
+/*************************************************
+* Fill the character property list *
+*************************************************/
+
+/* Checks whether the code points to an opcode that can take part in auto-
+possessification, and if so, fills a list with its properties.
+
+Arguments:
+ code points to start of expression
+ utf TRUE if in UTF mode
+ fcc points to the case-flipping table
+ list points to output list
+ list[0] will be filled with the opcode
+ list[1] will be non-zero if this opcode
+ can match an empty character string
+ list[2..7] depends on the opcode
+
+Returns: points to the start of the next opcode if *code is accepted
+ NULL if *code is not accepted
+*/
+
+static PCRE2_SPTR
+get_chr_property_list(PCRE2_SPTR code, BOOL utf, const uint8_t *fcc,
+ uint32_t *list)
+{
+PCRE2_UCHAR c = *code;
+PCRE2_UCHAR base;
+PCRE2_SPTR end;
+uint32_t chr;
+
+#ifdef SUPPORT_UNICODE
+uint32_t *clist_dest;
+const uint32_t *clist_src;
+#else
+(void)utf; /* Suppress "unused parameter" compiler warning */
+#endif
+
+list[0] = c;
+list[1] = FALSE;
+code++;
+
+if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
+ {
+ base = get_repeat_base(c);
+ c -= (base - OP_STAR);
+
+ if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO)
+ code += IMM2_SIZE;
+
+ list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT &&
+ c != OP_POSPLUS);
+
+ switch(base)
+ {
+ case OP_STAR:
+ list[0] = OP_CHAR;
+ break;
+
+ case OP_STARI:
+ list[0] = OP_CHARI;
+ break;
+
+ case OP_NOTSTAR:
+ list[0] = OP_NOT;
+ break;
+
+ case OP_NOTSTARI:
+ list[0] = OP_NOTI;
+ break;
+
+ case OP_TYPESTAR:
+ list[0] = *code;
+ code++;
+ break;
+ }
+ c = list[0];
+ }
+
+switch(c)
+ {
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_DOLL:
+ case OP_DOLLM:
+ return code;
+
+ case OP_CHAR:
+ case OP_NOT:
+ GETCHARINCTEST(chr, code);
+ list[2] = chr;
+ list[3] = NOTACHAR;
+ return code;
+
+ case OP_CHARI:
+ case OP_NOTI:
+ list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT;
+ GETCHARINCTEST(chr, code);
+ list[2] = chr;
+
+#ifdef SUPPORT_UNICODE
+ if (chr < 128 || (chr < 256 && !utf))
+ list[3] = fcc[chr];
+ else
+ list[3] = UCD_OTHERCASE(chr);
+#elif defined SUPPORT_WIDE_CHARS
+ list[3] = (chr < 256) ? fcc[chr] : chr;
+#else
+ list[3] = fcc[chr];
+#endif
+
+ /* The othercase might be the same value. */
+
+ if (chr == list[3])
+ list[3] = NOTACHAR;
+ else
+ list[4] = NOTACHAR;
+ return code;
+
+#ifdef SUPPORT_UNICODE
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (code[0] != PT_CLIST)
+ {
+ list[2] = code[0];
+ list[3] = code[1];
+ return code + 2;
+ }
+
+ /* Convert only if we have enough space. */
+
+ clist_src = PRIV(ucd_caseless_sets) + code[1];
+ clist_dest = list + 2;
+ code += 2;
+
+ do {
+ if (clist_dest >= list + 8)
+ {
+ /* Early return if there is not enough space. This should never
+ happen, since all clists are shorter than 5 character now. */
+ list[2] = code[0];
+ list[3] = code[1];
+ return code;
+ }
+ *clist_dest++ = *clist_src;
+ }
+ while(*clist_src++ != NOTACHAR);
+
+ /* All characters are stored. The terminating NOTACHAR is copied from the
+ clist itself. */
+
+ list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT;
+ return code;
+#endif
+
+ case OP_NCLASS:
+ case OP_CLASS:
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ if (c == OP_XCLASS)
+ end = code + GET(code, 0) - 1;
+ else
+#endif
+ end = code + 32 / sizeof(PCRE2_UCHAR);
+
+ switch(*end)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
+ list[1] = TRUE;
+ end++;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
+ end++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ list[1] = (GET2(end, 1) == 0);
+ end += 1 + 2 * IMM2_SIZE;
+ break;
+ }
+ list[2] = (uint32_t)(end - code);
+ return end;
+ }
+return NULL; /* Opcode not accepted */
+}
+
+
+
+/*************************************************
+* Scan further character sets for match *
+*************************************************/
+
+/* Checks whether the base and the current opcode have a common character, in
+which case the base cannot be possessified.
+
+Arguments:
+ code points to the byte code
+ utf TRUE in UTF mode
+ cb compile data block
+ base_list the data list of the base opcode
+ base_end the end of the data list
+ rec_limit points to recursion depth counter
+
+Returns: TRUE if the auto-possessification is possible
+*/
+
+static BOOL
+compare_opcodes(PCRE2_SPTR code, BOOL utf, const compile_block *cb,
+ const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit)
+{
+PCRE2_UCHAR c;
+uint32_t list[8];
+const uint32_t *chr_ptr;
+const uint32_t *ochr_ptr;
+const uint32_t *list_ptr;
+PCRE2_SPTR next_code;
+#ifdef SUPPORT_WIDE_CHARS
+PCRE2_SPTR xclass_flags;
+#endif
+const uint8_t *class_bitset;
+const uint8_t *set1, *set2, *set_end;
+uint32_t chr;
+BOOL accepted, invert_bits;
+BOOL entered_a_group = FALSE;
+
+if (--(*rec_limit) <= 0) return FALSE; /* Recursion has gone too deep */
+
+/* Note: the base_list[1] contains whether the current opcode has a greedy
+(represented by a non-zero value) quantifier. This is a different from
+other character type lists, which store here that the character iterator
+matches to an empty string (also represented by a non-zero value). */
+
+for(;;)
+ {
+ /* All operations move the code pointer forward.
+ Therefore infinite recursions are not possible. */
+
+ c = *code;
+
+ /* Skip over callouts */
+
+ if (c == OP_CALLOUT)
+ {
+ code += PRIV(OP_lengths)[c];
+ continue;
+ }
+
+ if (c == OP_CALLOUT_STR)
+ {
+ code += GET(code, 1 + 2*LINK_SIZE);
+ continue;
+ }
+
+ if (c == OP_ALT)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ }
+
+ switch(c)
+ {
+ case OP_END:
+ case OP_KETRPOS:
+ /* TRUE only in greedy case. The non-greedy case could be replaced by
+ an OP_EXACT, but it is probably not worth it. (And note that OP_EXACT
+ uses more memory, which we cannot get at this stage.) */
+
+ return base_list[1] != 0;
+
+ case OP_KET:
+ /* If the bracket is capturing, and referenced by an OP_RECURSE, or
+ it is an atomic sub-pattern (assert, once, etc.) the non-greedy case
+ cannot be converted to a possessive form. */
+
+ if (base_list[1] == 0) return FALSE;
+
+ switch(*(code - GET(code, 1)))
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+
+ /* Atomic sub-patterns and assertions can always auto-possessify their
+ last iterator. However, if the group was entered as a result of checking
+ a previous iterator, this is not possible. */
+
+ return !entered_a_group;
+ }
+
+ code += PRIV(OP_lengths)[c];
+ continue;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ next_code = code + GET(code, 1);
+ code += PRIV(OP_lengths)[c];
+
+ /* Check each branch. We have to recurse a level for all but the last
+ branch. */
+
+ while (*next_code == OP_ALT)
+ {
+ if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit))
+ return FALSE;
+ code = next_code + 1 + LINK_SIZE;
+ next_code += GET(next_code, 1);
+ }
+
+ entered_a_group = TRUE;
+ continue;
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+
+ next_code = code + 1;
+ if (*next_code != OP_BRA && *next_code != OP_CBRA
+ && *next_code != OP_ONCE && *next_code != OP_ONCE_NC) return FALSE;
+
+ do next_code += GET(next_code, 1); while (*next_code == OP_ALT);
+
+ /* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */
+
+ next_code += 1 + LINK_SIZE;
+ if (!compare_opcodes(next_code, utf, cb, base_list, base_end, rec_limit))
+ return FALSE;
+
+ code += PRIV(OP_lengths)[c];
+ continue;
+
+ default:
+ break;
+ }
+
+ /* Check for a supported opcode, and load its properties. */
+
+ code = get_chr_property_list(code, utf, cb->fcc, list);
+ if (code == NULL) return FALSE; /* Unsupported */
+
+ /* If either opcode is a small character list, set pointers for comparing
+ characters from that list with another list, or with a property. */
+
+ if (base_list[0] == OP_CHAR)
+ {
+ chr_ptr = base_list + 2;
+ list_ptr = list;
+ }
+ else if (list[0] == OP_CHAR)
+ {
+ chr_ptr = list + 2;
+ list_ptr = base_list;
+ }
+
+ /* Character bitsets can also be compared to certain opcodes. */
+
+ else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */
+ || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS))
+#endif
+ )
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS))
+#else
+ if (base_list[0] == OP_CLASS)
+#endif
+ {
+ set1 = (uint8_t *)(base_end - base_list[2]);
+ list_ptr = list;
+ }
+ else
+ {
+ set1 = (uint8_t *)(code - list[2]);
+ list_ptr = base_list;
+ }
+
+ invert_bits = FALSE;
+ switch(list_ptr[0])
+ {
+ case OP_CLASS:
+ case OP_NCLASS:
+ set2 = (uint8_t *)
+ ((list_ptr == list ? code : base_end) - list_ptr[2]);
+ break;
+
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE;
+ if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE;
+ if ((*xclass_flags & XCL_MAP) == 0)
+ {
+ /* No bits are set for characters < 256. */
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+ set2 = (uint8_t *)(xclass_flags + 1);
+ break;
+#endif
+
+ case OP_NOT_DIGIT:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_DIGIT:
+ set2 = (uint8_t *)(cb->cbits + cbit_digit);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_WHITESPACE:
+ set2 = (uint8_t *)(cb->cbits + cbit_space);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_WORDCHAR:
+ set2 = (uint8_t *)(cb->cbits + cbit_word);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* Because the bit sets are unaligned bytes, we need to perform byte
+ comparison here. */
+
+ set_end = set1 + 32;
+ if (invert_bits)
+ {
+ do
+ {
+ if ((*set1++ & ~(*set2++)) != 0) return FALSE;
+ }
+ while (set1 < set_end);
+ }
+ else
+ {
+ do
+ {
+ if ((*set1++ & *set2++) != 0) return FALSE;
+ }
+ while (set1 < set_end);
+ }
+
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+
+ /* Some property combinations also acceptable. Unicode property opcodes are
+ processed specially; the rest can be handled with a lookup table. */
+
+ else
+ {
+ uint32_t leftop, rightop;
+
+ leftop = base_list[0];
+ rightop = list[0];
+
+#ifdef SUPPORT_UNICODE
+ accepted = FALSE; /* Always set in non-unicode case. */
+ if (leftop == OP_PROP || leftop == OP_NOTPROP)
+ {
+ if (rightop == OP_EOD)
+ accepted = TRUE;
+ else if (rightop == OP_PROP || rightop == OP_NOTPROP)
+ {
+ int n;
+ const uint8_t *p;
+ BOOL same = leftop == rightop;
+ BOOL lisprop = leftop == OP_PROP;
+ BOOL risprop = rightop == OP_PROP;
+ BOOL bothprop = lisprop && risprop;
+
+ /* There's a table that specifies how each combination is to be
+ processed:
+ 0 Always return FALSE (never auto-possessify)
+ 1 Character groups are distinct (possessify if both are OP_PROP)
+ 2 Check character categories in the same group (general or particular)
+ 3 Return TRUE if the two opcodes are not the same
+ ... see comments below
+ */
+
+ n = propposstab[base_list[2]][list[2]];
+ switch(n)
+ {
+ case 0: break;
+ case 1: accepted = bothprop; break;
+ case 2: accepted = (base_list[3] == list[3]) != same; break;
+ case 3: accepted = !same; break;
+
+ case 4: /* Left general category, right particular category */
+ accepted = risprop && catposstab[base_list[3]][list[3]] == same;
+ break;
+
+ case 5: /* Right general category, left particular category */
+ accepted = lisprop && catposstab[list[3]][base_list[3]] == same;
+ break;
+
+ /* This code is logically tricky. Think hard before fiddling with it.
+ The posspropstab table has four entries per row. Each row relates to
+ one of PCRE's special properties such as ALNUM or SPACE or WORD.
+ Only WORD actually needs all four entries, but using repeats for the
+ others means they can all use the same code below.
+
+ The first two entries in each row are Unicode general categories, and
+ apply always, because all the characters they include are part of the
+ PCRE character set. The third and fourth entries are a general and a
+ particular category, respectively, that include one or more relevant
+ characters. One or the other is used, depending on whether the check
+ is for a general or a particular category. However, in both cases the
+ category contains more characters than the specials that are defined
+ for the property being tested against. Therefore, it cannot be used
+ in a NOTPROP case.
+
+ Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po.
+ Underscore is covered by ucp_P or ucp_Po. */
+
+ case 6: /* Left alphanum vs right general category */
+ case 7: /* Left space vs right general category */
+ case 8: /* Left word vs right general category */
+ p = posspropstab[n-6];
+ accepted = risprop && lisprop ==
+ (list[3] != p[0] &&
+ list[3] != p[1] &&
+ (list[3] != p[2] || !lisprop));
+ break;
+
+ case 9: /* Right alphanum vs left general category */
+ case 10: /* Right space vs left general category */
+ case 11: /* Right word vs left general category */
+ p = posspropstab[n-9];
+ accepted = lisprop && risprop ==
+ (base_list[3] != p[0] &&
+ base_list[3] != p[1] &&
+ (base_list[3] != p[2] || !risprop));
+ break;
+
+ case 12: /* Left alphanum vs right particular category */
+ case 13: /* Left space vs right particular category */
+ case 14: /* Left word vs right particular category */
+ p = posspropstab[n-12];
+ accepted = risprop && lisprop ==
+ (catposstab[p[0]][list[3]] &&
+ catposstab[p[1]][list[3]] &&
+ (list[3] != p[3] || !lisprop));
+ break;
+
+ case 15: /* Right alphanum vs left particular category */
+ case 16: /* Right space vs left particular category */
+ case 17: /* Right word vs left particular category */
+ p = posspropstab[n-15];
+ accepted = lisprop && risprop ==
+ (catposstab[p[0]][base_list[3]] &&
+ catposstab[p[1]][base_list[3]] &&
+ (base_list[3] != p[3] || !risprop));
+ break;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UNICODE */
+
+ accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP &&
+ rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP &&
+ autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP];
+
+ if (!accepted) return FALSE;
+
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+
+ /* Control reaches here only if one of the items is a small character list.
+ All characters are checked against the other side. */
+
+ do
+ {
+ chr = *chr_ptr;
+
+ switch(list_ptr[0])
+ {
+ case OP_CHAR:
+ ochr_ptr = list_ptr + 2;
+ do
+ {
+ if (chr == *ochr_ptr) return FALSE;
+ ochr_ptr++;
+ }
+ while(*ochr_ptr != NOTACHAR);
+ break;
+
+ case OP_NOT:
+ ochr_ptr = list_ptr + 2;
+ do
+ {
+ if (chr == *ochr_ptr)
+ break;
+ ochr_ptr++;
+ }
+ while(*ochr_ptr != NOTACHAR);
+ if (*ochr_ptr == NOTACHAR) return FALSE; /* Not found */
+ break;
+
+ /* Note that OP_DIGIT etc. are generated only when PCRE2_UCP is *not*
+ set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
+
+ case OP_DIGIT:
+ if (chr < 256 && (cb->ctypes[chr] & ctype_digit) != 0) return FALSE;
+ break;
+
+ case OP_NOT_DIGIT:
+ if (chr > 255 || (cb->ctypes[chr] & ctype_digit) == 0) return FALSE;
+ break;
+
+ case OP_WHITESPACE:
+ if (chr < 256 && (cb->ctypes[chr] & ctype_space) != 0) return FALSE;
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (chr > 255 || (cb->ctypes[chr] & ctype_space) == 0) return FALSE;
+ break;
+
+ case OP_WORDCHAR:
+ if (chr < 255 && (cb->ctypes[chr] & ctype_word) != 0) return FALSE;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (chr > 255 || (cb->ctypes[chr] & ctype_word) == 0) return FALSE;
+ break;
+
+ case OP_HSPACE:
+ switch(chr)
+ {
+ HSPACE_CASES: return FALSE;
+ default: break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(chr)
+ {
+ HSPACE_CASES: break;
+ default: return FALSE;
+ }
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ switch(chr)
+ {
+ VSPACE_CASES: return FALSE;
+ default: break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(chr)
+ {
+ VSPACE_CASES: break;
+ default: return FALSE;
+ }
+ break;
+
+ case OP_DOLL:
+ case OP_EODN:
+ switch (chr)
+ {
+ case CHAR_CR:
+ case CHAR_LF:
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ return FALSE;
+ }
+ break;
+
+ case OP_EOD: /* Can always possessify before \z */
+ break;
+
+#ifdef SUPPORT_UNICODE
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (!check_char_prop(chr, list_ptr[2], list_ptr[3],
+ list_ptr[0] == OP_NOTPROP))
+ return FALSE;
+ break;
+#endif
+
+ case OP_NCLASS:
+ if (chr > 255) return FALSE;
+ /* Fall through */
+
+ case OP_CLASS:
+ if (chr > 255) break;
+ class_bitset = (uint8_t *)
+ ((list_ptr == list ? code : base_end) - list_ptr[2]);
+ if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE;
+ break;
+
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) -
+ list_ptr[2] + LINK_SIZE, utf)) return FALSE;
+ break;
+#endif
+
+ default:
+ return FALSE;
+ }
+
+ chr_ptr++;
+ }
+ while(*chr_ptr != NOTACHAR);
+
+ /* At least one character must be matched from this opcode. */
+
+ if (list[1] == 0) return TRUE;
+ }
+
+/* Control never reaches here. There used to be a fail-save return FALSE; here,
+but some compilers complain about an unreachable statement. */
+}
+
+
+
+/*************************************************
+* Scan compiled regex for auto-possession *
+*************************************************/
+
+/* Replaces single character iterations with their possessive alternatives
+if appropriate. This function modifies the compiled opcode! Hitting a
+non-existent opcode may indicate a bug in PCRE2, but it can also be caused if a
+bad UTF string was compiled with PCRE2_NO_UTF_CHECK. The rec_limit catches
+overly complicated or large patterns. In these cases, the check just stops,
+leaving the remainder of the pattern unpossessified.
+
+Arguments:
+ code points to start of the byte code
+ utf TRUE in UTF mode
+ cb compile data block
+
+Returns: 0 for success
+ -1 if a non-existant opcode is encountered
+*/
+
+int
+PRIV(auto_possessify)(PCRE2_UCHAR *code, BOOL utf, const compile_block *cb)
+{
+PCRE2_UCHAR c;
+PCRE2_SPTR end;
+PCRE2_UCHAR *repeat_opcode;
+uint32_t list[8];
+int rec_limit = 1000; /* Was 10,000 but clang+ASAN uses a lot of stack. */
+
+for (;;)
+ {
+ c = *code;
+
+ if (c > OP_TABLE_LENGTH) return -1; /* Something gone wrong */
+
+ if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
+ {
+ c -= get_repeat_base(c) - OP_STAR;
+ end = (c <= OP_MINUPTO) ?
+ get_chr_property_list(code, utf, cb->fcc, list) : NULL;
+ list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
+
+ if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit))
+ {
+ switch(c)
+ {
+ case OP_STAR:
+ *code += OP_POSSTAR - OP_STAR;
+ break;
+
+ case OP_MINSTAR:
+ *code += OP_POSSTAR - OP_MINSTAR;
+ break;
+
+ case OP_PLUS:
+ *code += OP_POSPLUS - OP_PLUS;
+ break;
+
+ case OP_MINPLUS:
+ *code += OP_POSPLUS - OP_MINPLUS;
+ break;
+
+ case OP_QUERY:
+ *code += OP_POSQUERY - OP_QUERY;
+ break;
+
+ case OP_MINQUERY:
+ *code += OP_POSQUERY - OP_MINQUERY;
+ break;
+
+ case OP_UPTO:
+ *code += OP_POSUPTO - OP_UPTO;
+ break;
+
+ case OP_MINUPTO:
+ *code += OP_POSUPTO - OP_MINUPTO;
+ break;
+ }
+ }
+ c = *code;
+ }
+ else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS)
+ {
+#ifdef SUPPORT_WIDE_CHARS
+ if (c == OP_XCLASS)
+ repeat_opcode = code + GET(code, 1);
+ else
+#endif
+ repeat_opcode = code + 1 + (32 / sizeof(PCRE2_UCHAR));
+
+ c = *repeat_opcode;
+ if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)
+ {
+ /* end must not be NULL. */
+ end = get_chr_property_list(code, utf, cb->fcc, list);
+
+ list[1] = (c & 1) == 0;
+
+ if (compare_opcodes(end, utf, cb, list, end, &rec_limit))
+ {
+ switch (c)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ *repeat_opcode = OP_CRPOSSTAR;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ *repeat_opcode = OP_CRPOSPLUS;
+ break;
+
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ *repeat_opcode = OP_CRPOSQUERY;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ *repeat_opcode = OP_CRPOSRANGE;
+ break;
+ }
+ }
+ }
+ c = *code;
+ }
+
+ switch(c)
+ {
+ case OP_END:
+ return 0;
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
+ code += 2;
+ break;
+
+ case OP_CALLOUT_STR:
+ code += GET(code, 1 + 2*LINK_SIZE);
+ break;
+
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ code += GET(code, 1);
+ break;
+#endif
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ code += PRIV(OP_lengths)[c];
+
+ /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be
+ followed by a multi-byte character. The length in the table is a minimum, so
+ we have to arrange to skip the extra code units. */
+
+#ifdef MAYBE_UTF_MULTI
+ if (utf) switch(c)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif /* SUPPORT_WIDE_CHARS */
+ }
+}
+
+/* End of pcre2_auto_possess.c */
diff --git a/thirdparty/pcre2/src/pcre2_chartables.c b/thirdparty/pcre2/src/pcre2_chartables.c
new file mode 100644
index 0000000000..203cb1a4ab
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_chartables.c
@@ -0,0 +1,198 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* This file contains character tables that are used when no external tables
+are passed to PCRE2 by the application that calls it. The tables are used only
+for characters whose code values are less than 256.
+
+This is a default version of the tables that assumes ASCII encoding. A program
+called dftables (which is distributed with PCRE2) can be used to build
+alternative versions of this file. This is necessary if you are running in an
+EBCDIC environment, or if you want to default to a different encoding, for
+example ISO-8859-1. When dftables is run, it creates these tables in the
+current locale. If PCRE2 is configured with --enable-rebuild-chartables, this
+happens automatically.
+
+The following #includes are present because without them gcc 4.x may remove the
+array definition from the final binary if PCRE2 is built into a static library
+and dead code stripping is activated. This leads to link errors. Pulling in the
+header ensures that the array gets flagged as "someone outside this compilation
+unit might reference this" and so it will always be supplied to the linker. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+const uint8_t PRIV(default_tables)[] = {
+
+/* This table is a lower casing table. */
+
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,
+ 136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,
+ 152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,
+ 168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,
+ 184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,
+ 200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,
+ 232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,
+ 248,249,250,251,252,253,254,255,
+
+/* This table is a case flipping table. */
+
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,
+ 136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,
+ 152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,
+ 168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,
+ 184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,
+ 200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,
+ 232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,
+ 248,249,250,251,252,253,254,255,
+
+/* This table contains bit maps for various character classes. Each map is 32
+bytes long and the bits run from the least significant end of each byte. The
+classes that have their own maps are: space, xdigit, digit, upper, lower, word,
+graph, print, punct, and cntrl. Other classes are built from combinations. */
+
+ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
+ 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+/* This table identifies various classes of character by individual bits:
+ 0x01 white space character
+ 0x02 letter
+ 0x04 decimal digit
+ 0x08 hexadecimal digit
+ 0x10 alphanumeric or '_'
+ 0x80 regular expression metacharacter or binary zero
+*/
+
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
+ 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
+ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
+ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
+ 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
+ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
+
+/* End of pcre2_chartables.c */
diff --git a/thirdparty/pcre2/src/pcre2_compile.c b/thirdparty/pcre2/src/pcre2_compile.c
new file mode 100644
index 0000000000..6d98a68caa
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_compile.c
@@ -0,0 +1,9517 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK cb /* Block containing newline information */
+#define PSSTART start_pattern /* Field containing processed string start */
+#define PSEND end_pattern /* Field containing processed string end */
+
+#include "pcre2_internal.h"
+
+/* In rare error cases debugging might require calling pcre2_printint(). */
+
+#if 0
+#ifdef EBCDIC
+#define PRINTABLE(c) ((c) >= 64 && (c) < 255)
+#else
+#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
+#endif
+#include "pcre2_printint.c"
+#define DEBUG_CALL_PRINTINT
+#endif
+
+/* Other debugging code can be enabled by these defines. */
+
+// #define DEBUG_SHOW_CAPTURES
+// #define DEBUG_SHOW_PARSED
+
+/* There are a few things that vary with different code unit sizes. Handle them
+by defining macros in order to minimize #if usage. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define STRING_UTFn_RIGHTPAR STRING_UTF8_RIGHTPAR, 5
+#define XDIGIT(c) xdigitab[c]
+
+#else /* Either 16-bit or 32-bit */
+#define XDIGIT(c) (MAX_255(c)? xdigitab[c] : 0xff)
+
+#if PCRE2_CODE_UNIT_WIDTH == 16
+#define STRING_UTFn_RIGHTPAR STRING_UTF16_RIGHTPAR, 6
+
+#else /* 32-bit */
+#define STRING_UTFn_RIGHTPAR STRING_UTF32_RIGHTPAR, 6
+#endif
+#endif
+
+/* Macros to store and retrieve a PCRE2_SIZE value in the parsed pattern, which
+consists of uint32_t elements. Assume that if uint32_t can't hold it, two of
+them will be able to (i.e. assume a 64-bit world). */
+
+#if PCRE2_SIZE_MAX <= UINT32_MAX
+#define PUTOFFSET(s,p) *p++ = s
+#define GETOFFSET(s,p) s = *p++
+#define GETPLUSOFFSET(s,p) s = *(++p)
+#define READPLUSOFFSET(s,p) s = p[1]
+#define SKIPOFFSET(p) p++
+#define SIZEOFFSET 1
+#else
+#define PUTOFFSET(s,p) \
+ { *p++ = (uint32_t)(s >> 32); *p++ = (uint32_t)(s & 0xffffffff); }
+#define GETOFFSET(s,p) \
+ { s = ((PCRE2_SIZE)p[0] << 32) | (PCRE2_SIZE)p[1]; p += 2; }
+#define GETPLUSOFFSET(s,p) \
+ { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; p += 2; }
+#define READPLUSOFFSET(s,p) \
+ { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; }
+#define SKIPOFFSET(p) p += 2
+#define SIZEOFFSET 2
+#endif
+
+/* Macros for manipulating elements of the parsed pattern vector. */
+
+#define META_CODE(x) (x & 0xffff0000u)
+#define META_DATA(x) (x & 0x0000ffffu)
+#define META_DIFF(x,y) ((x-y)>>16)
+
+/* Function definitions to allow mutual recursion */
+
+#ifdef SUPPORT_UNICODE
+static unsigned int
+ add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t,
+ compile_block *, const uint32_t *, unsigned int);
+#endif
+
+static int
+ compile_regex(uint32_t, PCRE2_UCHAR **, uint32_t **, int *, uint32_t,
+ uint32_t *, int32_t *, uint32_t *, int32_t *, branch_chain *,
+ compile_block *, PCRE2_SIZE *);
+
+static int
+ get_branchlength(uint32_t **, int *, int *, parsed_recurse_check *,
+ compile_block *);
+
+static BOOL
+ set_lookbehind_lengths(uint32_t **, int *, int *, parsed_recurse_check *,
+ compile_block *);
+
+
+
+/*************************************************
+* Code parameters and static tables *
+*************************************************/
+
+#define MAX_GROUP_NUMBER 65535u
+#define MAX_REPEAT_COUNT 65535u
+#define REPEAT_UNLIMITED (MAX_REPEAT_COUNT+1)
+
+/* COMPILE_WORK_SIZE specifies the size of stack workspace, which is used in
+different ways in the different pattern scans. The parsing and group-
+identifying pre-scan uses it to handle nesting, and needs it to be 16-bit
+aligned for this. Having defined the size in code units, we set up
+C16_WORK_SIZE as the number of elements in the 16-bit vector.
+
+During the first compiling phase, when determining how much memory is required,
+the regex is partly compiled into this space, but the compiled parts are
+discarded as soon as they can be, so that hopefully there will never be an
+overrun. The code does, however, check for an overrun, which can occur for
+pathological patterns. The size of the workspace depends on LINK_SIZE because
+the length of compiled items varies with this.
+
+In the real compile phase, this workspace is not currently used. */
+
+#define COMPILE_WORK_SIZE (2048*LINK_SIZE) /* Size in code units */
+
+#define C16_WORK_SIZE \
+ ((COMPILE_WORK_SIZE * sizeof(PCRE2_UCHAR))/sizeof(uint16_t))
+
+/* A uint32_t vector is used for caching information about the size of
+capturing groups, to improve performance. A default is created on the stack of
+this size. */
+
+#define GROUPINFO_DEFAULT_SIZE 256
+
+/* The overrun tests check for a slightly smaller size so that they detect the
+overrun before it actually does run off the end of the data block. */
+
+#define WORK_SIZE_SAFETY_MARGIN (100)
+
+/* This value determines the size of the initial vector that is used for
+remembering named groups during the pre-compile. It is allocated on the stack,
+but if it is too small, it is expanded, in a similar way to the workspace. The
+value is the number of slots in the list. */
+
+#define NAMED_GROUP_LIST_SIZE 20
+
+/* The pre-compiling pass over the pattern creates a parsed pattern in a vector
+of uint32_t. For short patterns this lives on the stack, with this size. Heap
+memory is used for longer patterns. */
+
+#define PARSED_PATTERN_DEFAULT_SIZE 1024
+
+/* Maximum length value to check against when making sure that the variable
+that holds the compiled pattern length does not overflow. We make it a bit less
+than INT_MAX to allow for adding in group terminating code units, so that we
+don't have to check them every time. */
+
+#define OFLOW_MAX (INT_MAX - 20)
+
+/* Code values for parsed patterns, which are stored in a vector of 32-bit
+unsigned ints. Values less than META_END are literal data values. The coding
+for identifying the item is in the top 16-bits, leaving 16 bits for the
+additional data that some of them need. The META_CODE, META_DATA, and META_DIFF
+macros are used to manipulate parsed pattern elements.
+
+NOTE: When these definitions are changed, the table of extra lengths for each
+code (meta_extra_lengths, just below) must be updated to remain in step. */
+
+#define META_END 0x80000000u /* End of pattern */
+
+#define META_ALT 0x80010000u /* alternation */
+#define META_ATOMIC 0x80020000u /* atomic group */
+#define META_BACKREF 0x80030000u /* Back ref */
+#define META_BACKREF_BYNAME 0x80040000u /* \k'name' */
+#define META_BIGVALUE 0x80050000u /* Next is a literal > META_END */
+#define META_CALLOUT_NUMBER 0x80060000u /* (?C with numerical argument */
+#define META_CALLOUT_STRING 0x80070000u /* (?C with string argument */
+#define META_CAPTURE 0x80080000u /* Capturing parenthesis */
+#define META_CIRCUMFLEX 0x80090000u /* ^ metacharacter */
+#define META_CLASS 0x800a0000u /* start non-empty class */
+#define META_CLASS_EMPTY 0x800b0000u /* empty class */
+#define META_CLASS_EMPTY_NOT 0x800c0000u /* negative empty class */
+#define META_CLASS_END 0x800d0000u /* end of non-empty class */
+#define META_CLASS_NOT 0x800e0000u /* start non-empty negative class */
+#define META_COND_ASSERT 0x800f0000u /* (?(?assertion)... */
+#define META_COND_DEFINE 0x80100000u /* (?(DEFINE)... */
+#define META_COND_NAME 0x80110000u /* (?(<name>)... */
+#define META_COND_NUMBER 0x80120000u /* (?(digits)... */
+#define META_COND_RNAME 0x80130000u /* (?(R&name)... */
+#define META_COND_RNUMBER 0x80140000u /* (?(Rdigits)... */
+#define META_COND_VERSION 0x80150000u /* (?(VERSION<op>x.y)... */
+#define META_DOLLAR 0x80160000u /* $ metacharacter */
+#define META_DOT 0x80170000u /* . metacharacter */
+#define META_ESCAPE 0x80180000u /* \d and friends */
+#define META_KET 0x80190000u /* closing parenthesis */
+#define META_NOCAPTURE 0x801a0000u /* no capture parens */
+#define META_OPTIONS 0x801b0000u /* (?i) and friends */
+#define META_POSIX 0x801c0000u /* POSIX class item */
+#define META_POSIX_NEG 0x801d0000u /* negative POSIX class item */
+#define META_RANGE_ESCAPED 0x801e0000u /* range with at least one escape */
+#define META_RANGE_LITERAL 0x801f0000u /* range defined literally */
+#define META_RECURSE 0x80200000u /* Recursion */
+#define META_RECURSE_BYNAME 0x80210000u /* (?&name) */
+
+/* These must be kept together to make it easy to check that an assertion
+is present where expected in a conditional group. */
+
+#define META_LOOKAHEAD 0x80220000u /* (?= */
+#define META_LOOKAHEADNOT 0x80230000u /* (?! */
+#define META_LOOKBEHIND 0x80240000u /* (?<= */
+#define META_LOOKBEHINDNOT 0x80250000u /* (?<! */
+
+/* These must be kept in this order, with consecutive values, and the _ARG
+versions of PRUNE, SKIP, and THEN immediately after their non-argument
+versions. */
+
+#define META_MARK 0x80260000u /* (*MARK) */
+#define META_ACCEPT 0x80270000u /* (*ACCEPT) */
+#define META_COMMIT 0x80280000u /* (*COMMIT) */
+#define META_FAIL 0x80290000u /* (*FAIL) */
+#define META_PRUNE 0x802a0000u /* These pairs must */
+#define META_PRUNE_ARG 0x802b0000u /* be */
+#define META_SKIP 0x802c0000u /* kept */
+#define META_SKIP_ARG 0x802d0000u /* in */
+#define META_THEN 0x802e0000u /* this */
+#define META_THEN_ARG 0x802f0000u /* order */
+
+/* These must be kept in groups of adjacent 3 values, and all together. */
+
+#define META_ASTERISK 0x80300000u /* * */
+#define META_ASTERISK_PLUS 0x80310000u /* *+ */
+#define META_ASTERISK_QUERY 0x80320000u /* *? */
+#define META_PLUS 0x80330000u /* + */
+#define META_PLUS_PLUS 0x80340000u /* ++ */
+#define META_PLUS_QUERY 0x80350000u /* +? */
+#define META_QUERY 0x80360000u /* ? */
+#define META_QUERY_PLUS 0x80370000u /* ?+ */
+#define META_QUERY_QUERY 0x80380000u /* ?? */
+#define META_MINMAX 0x80390000u /* {n,m} repeat */
+#define META_MINMAX_PLUS 0x803a0000u /* {n,m}+ repeat */
+#define META_MINMAX_QUERY 0x803b0000u /* {n,m}? repeat */
+
+#define META_FIRST_QUANTIFIER META_ASTERISK
+#define META_LAST_QUANTIFIER META_MINMAX_QUERY
+
+/* Table of extra lengths for each of the meta codes. Must be kept in step with
+the definitions above. For some items these values are a basic length to which
+a variable amount has to be added. */
+
+static unsigned char meta_extra_lengths[] = {
+ 0, /* META_END */
+ 0, /* META_ALT */
+ 0, /* META_ATOMIC */
+ 0, /* META_BACKREF - more if group is >= 10 */
+ 1+SIZEOFFSET, /* META_BACKREF_BYNAME */
+ 1, /* META_BIGVALUE */
+ 3, /* META_CALLOUT_NUMBER */
+ 3+SIZEOFFSET, /* META_CALLOUT_STRING */
+ 0, /* META_CAPTURE */
+ 0, /* META_CIRCUMFLEX */
+ 0, /* META_CLASS */
+ 0, /* META_CLASS_EMPTY */
+ 0, /* META_CLASS_EMPTY_NOT */
+ 0, /* META_CLASS_END */
+ 0, /* META_CLASS_NOT */
+ 0, /* META_COND_ASSERT */
+ SIZEOFFSET, /* META_COND_DEFINE */
+ 1+SIZEOFFSET, /* META_COND_NAME */
+ 1+SIZEOFFSET, /* META_COND_NUMBER */
+ 1+SIZEOFFSET, /* META_COND_RNAME */
+ 1+SIZEOFFSET, /* META_COND_RNUMBER */
+ 3, /* META_COND_VERSION */
+ 0, /* META_DOLLAR */
+ 0, /* META_DOT */
+ 0, /* META_ESCAPE - more for ESC_P, ESC_p, ESC_g, ESC_k */
+ 0, /* META_KET */
+ 0, /* META_NOCAPTURE */
+ 1, /* META_OPTIONS */
+ 1, /* META_POSIX */
+ 1, /* META_POSIX_NEG */
+ 0, /* META_RANGE_ESCAPED */
+ 0, /* META_RANGE_LITERAL */
+ SIZEOFFSET, /* META_RECURSE */
+ 1+SIZEOFFSET, /* META_RECURSE_BYNAME */
+ 0, /* META_LOOKAHEAD */
+ 0, /* META_LOOKAHEADNOT */
+ SIZEOFFSET, /* META_LOOKBEHIND */
+ SIZEOFFSET, /* META_LOOKBEHINDNOT */
+ 1, /* META_MARK - plus the string length */
+ 0, /* META_ACCEPT */
+ 0, /* META_COMMIT */
+ 0, /* META_FAIL */
+ 0, /* META_PRUNE */
+ 1, /* META_PRUNE_ARG - plus the string length */
+ 0, /* META_SKIP */
+ 1, /* META_SKIP_ARG - plus the string length */
+ 0, /* META_THEN */
+ 1, /* META_THEN_ARG - plus the string length */
+ 0, /* META_ASTERISK */
+ 0, /* META_ASTERISK_PLUS */
+ 0, /* META_ASTERISK_QUERY */
+ 0, /* META_PLUS */
+ 0, /* META_PLUS_PLUS */
+ 0, /* META_PLUS_QUERY */
+ 0, /* META_QUERY */
+ 0, /* META_QUERY_PLUS */
+ 0, /* META_QUERY_QUERY */
+ 2, /* META_MINMAX */
+ 2, /* META_MINMAX_PLUS */
+ 2 /* META_MINMAX_QUERY */
+};
+
+/* Types for skipping parts of a parsed pattern. */
+
+enum { PSKIP_ALT, PSKIP_CLASS, PSKIP_KET };
+
+/* Macro for setting individual bits in class bitmaps. It took some
+experimenting to figure out how to stop gcc 5.3.0 from warning with
+-Wconversion. This version gets a warning:
+
+ #define SETBIT(a,b) a[(b)/8] |= (uint8_t)(1 << ((b)&7))
+
+Let's hope the apparently less efficient version isn't actually so bad if the
+compiler is clever with identical subexpressions. */
+
+#define SETBIT(a,b) a[(b)/8] = (uint8_t)(a[(b)/8] | (1 << ((b)&7)))
+
+/* Private flags added to firstcu and reqcu. */
+
+#define REQ_CASELESS (1 << 0) /* Indicates caselessness */
+#define REQ_VARY (1 << 1) /* reqcu followed non-literal item */
+/* Negative values for the firstcu and reqcu flags */
+#define REQ_UNSET (-2) /* Not yet found anything */
+#define REQ_NONE (-1) /* Found not fixed char */
+
+/* These flags are used in the groupinfo vector. */
+
+#define GI_SET_FIXED_LENGTH 0x80000000u
+#define GI_NOT_FIXED_LENGTH 0x40000000u
+#define GI_FIXED_LENGTH_MASK 0x0000ffffu
+
+/* This simple test for a decimal digit works for both ASCII/Unicode and EBCDIC
+and is fast (a good compiler can turn it into a subtraction and unsigned
+comparison). */
+
+#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
+
+/* Table to identify hex digits. The tables in chartables are dependent on the
+locale, and may mark arbitrary characters as digits. We want to recognize only
+0-9, a-z, and A-Z as hex digits, which is why we have a private table here. It
+costs 256 bytes, but it is a lot faster than doing character value tests (at
+least in some simple cases I timed), and in some applications one wants PCRE2
+to compile efficiently as well as match efficiently. The value in the table is
+the binary hex digit value, or 0xff for non-hex digits. */
+
+/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
+UTF-8 mode. */
+
+#ifndef EBCDIC
+static const uint8_t xdigitab[] =
+ {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - ' */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ( - / */
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 */
+ 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff, /* 8 - ? */
+ 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* @ - G */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H - O */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* P - W */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* X - _ */
+ 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* ` - g */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h - o */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* p - w */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* x -127 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 128-135 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 136-143 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144-151 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 152-159 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160-167 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 168-175 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 176-183 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 192-199 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 2ff-207 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 208-215 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 216-223 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 224-231 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 232-239 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 240-247 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* 248-255 */
+
+#else
+
+/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
+
+static const uint8_t xdigitab[] =
+ {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 0 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 10 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 32- 39 20 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 40- 47 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 48- 55 30 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 56- 63 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - 71 40 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 72- | */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* & - 87 50 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 88- 95 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - -103 60 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 104- ? */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 112-119 70 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 120- " */
+ 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* 128- g 80 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h -143 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144- p 90 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* q -159 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160- x A0 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* y -175 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ^ -183 B0 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */
+ 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* { - G C0 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H -207 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* } - P D0 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Q -223 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* \ - X E0 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Y -239 */
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 F0 */
+ 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff};/* 8 -255 */
+#endif /* EBCDIC */
+
+
+/* Table for handling alphanumeric escaped characters. Positive returns are
+simple data values; negative values are for special things like \d and so on.
+Zero means further processing is needed (for things like \x), or the escape is
+invalid. */
+
+/* This is the "normal" table for ASCII systems or for EBCDIC systems running
+in UTF-8 mode. It runs from '0' to 'z'. */
+
+#ifndef EBCDIC
+#define ESCAPES_FIRST CHAR_0
+#define ESCAPES_LAST CHAR_z
+#define UPPER_CASE(c) (c-32)
+
+static const short int escapes[] = {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ CHAR_COLON, CHAR_SEMICOLON,
+ CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN,
+ CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK,
+ CHAR_COMMERCIAL_AT, -ESC_A,
+ -ESC_B, -ESC_C,
+ -ESC_D, -ESC_E,
+ 0, -ESC_G,
+ -ESC_H, 0,
+ 0, -ESC_K,
+ 0, 0,
+ -ESC_N, 0,
+ -ESC_P, -ESC_Q,
+ -ESC_R, -ESC_S,
+ 0, 0,
+ -ESC_V, -ESC_W,
+ -ESC_X, 0,
+ -ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
+ CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
+ CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
+ CHAR_GRAVE_ACCENT, ESC_a,
+ -ESC_b, 0,
+ -ESC_d, ESC_e,
+ ESC_f, 0,
+ -ESC_h, 0,
+ 0, -ESC_k,
+ 0, 0,
+ ESC_n, 0,
+ -ESC_p, 0,
+ ESC_r, -ESC_s,
+ ESC_tee, 0,
+ -ESC_v, -ESC_w,
+ 0, 0,
+ -ESC_z
+};
+
+#else
+
+/* This is the "abnormal" table for EBCDIC systems without UTF-8 support.
+It runs from 'a' to '9'. For some minimal testing of EBCDIC features, the code
+is sometimes compiled on an ASCII system. In this case, we must not use CHAR_a
+because it is defined as 'a', which of course picks up the ASCII value. */
+
+#if 'a' == 0x81 /* Check for a real EBCDIC environment */
+#define ESCAPES_FIRST CHAR_a
+#define ESCAPES_LAST CHAR_9
+#define UPPER_CASE(c) (c+64)
+#else /* Testing in an ASCII environment */
+#define ESCAPES_FIRST ((unsigned char)'\x81') /* EBCDIC 'a' */
+#define ESCAPES_LAST ((unsigned char)'\xf9') /* EBCDIC '9' */
+#define UPPER_CASE(c) (c-32)
+#endif
+
+static const short int escapes[] = {
+/* 80 */ ESC_a, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
+/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
+/* 90 */ 0, 0, -ESC_k, 0, 0, ESC_n, 0, -ESC_p,
+/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
+/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
+/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
+/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
+/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G,
+/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0,
+/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P,
+/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0,
+/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X,
+/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0,
+/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* F8 */ 0, 0
+};
+
+/* We also need a table of characters that may follow \c in an EBCDIC
+environment for characters 0-31. */
+
+static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
+
+#endif /* EBCDIC */
+
+
+/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
+searched linearly. Put all the names into a single string, in order to reduce
+the number of relocations when a shared library is dynamically linked. The
+string is built from string macros so that it works in UTF-8 mode on EBCDIC
+platforms. */
+
+typedef struct verbitem {
+ unsigned int len; /* Length of verb name */
+ uint32_t meta; /* Base META_ code */
+ int has_arg; /* Argument requirement */
+} verbitem;
+
+static const char verbnames[] =
+ "\0" /* Empty name is a shorthand for MARK */
+ STRING_MARK0
+ STRING_ACCEPT0
+ STRING_COMMIT0
+ STRING_F0
+ STRING_FAIL0
+ STRING_PRUNE0
+ STRING_SKIP0
+ STRING_THEN;
+
+static const verbitem verbs[] = {
+ { 0, META_MARK, +1 }, /* > 0 => must have an argument */
+ { 4, META_MARK, +1 },
+ { 6, META_ACCEPT, -1 }, /* < 0 => must not have an argument */
+ { 6, META_COMMIT, -1 },
+ { 1, META_FAIL, -1 },
+ { 4, META_FAIL, -1 },
+ { 5, META_PRUNE, 0 }, /* Argument is optional; bump META code if found */
+ { 4, META_SKIP, 0 },
+ { 4, META_THEN, 0 }
+};
+
+static const int verbcount = sizeof(verbs)/sizeof(verbitem);
+
+/* Verb opcodes, indexed by their META code offset from META_MARK. */
+
+static const uint32_t verbops[] = {
+ OP_MARK, OP_ACCEPT, OP_COMMIT, OP_FAIL, OP_PRUNE, OP_PRUNE_ARG, OP_SKIP,
+ OP_SKIP_ARG, OP_THEN, OP_THEN_ARG };
+
+/* Offsets from OP_STAR for case-independent and negative repeat opcodes. */
+
+static uint32_t chartypeoffset[] = {
+ OP_STAR - OP_STAR, OP_STARI - OP_STAR,
+ OP_NOTSTAR - OP_STAR, OP_NOTSTARI - OP_STAR };
+
+/* Tables of names of POSIX character classes and their lengths. The names are
+now all in a single string, to reduce the number of relocations when a shared
+library is dynamically loaded. The list of lengths is terminated by a zero
+length entry. The first three must be alpha, lower, upper, as this is assumed
+for handling case independence. The indices for graph, print, and punct are
+needed, so identify them. */
+
+static const char posix_names[] =
+ STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
+ STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
+ STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
+ STRING_word0 STRING_xdigit;
+
+static const uint8_t posix_name_lengths[] = {
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
+
+#define PC_GRAPH 8
+#define PC_PRINT 9
+#define PC_PUNCT 10
+
+/* Table of class bit maps for each POSIX class. Each class is formed from a
+base map, with an optional addition or removal of another map. Then, for some
+classes, there is some additional tweaking: for [:blank:] the vertical space
+characters are removed, and for [:alpha:] and [:alnum:] the underscore
+character is removed. The triples in the table consist of the base map offset,
+second map offset or -1 if no second map, and a non-negative value for map
+addition or a negative value for map subtraction (if there are two maps). The
+absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
+remove vertical space characters, 2 => remove underscore. */
+
+static const int posix_class_maps[] = {
+ cbit_word, cbit_digit, -2, /* alpha */
+ cbit_lower, -1, 0, /* lower */
+ cbit_upper, -1, 0, /* upper */
+ cbit_word, -1, 2, /* alnum - word without underscore */
+ cbit_print, cbit_cntrl, 0, /* ascii */
+ cbit_space, -1, 1, /* blank - a GNU extension */
+ cbit_cntrl, -1, 0, /* cntrl */
+ cbit_digit, -1, 0, /* digit */
+ cbit_graph, -1, 0, /* graph */
+ cbit_print, -1, 0, /* print */
+ cbit_punct, -1, 0, /* punct */
+ cbit_space, -1, 0, /* space */
+ cbit_word, -1, 0, /* word - a Perl extension */
+ cbit_xdigit,-1, 0 /* xdigit */
+};
+
+#ifdef SUPPORT_UNICODE
+
+/* The POSIX class Unicode property substitutes that are used in UCP mode must
+be in the order of the POSIX class names, defined above. */
+
+static int posix_substitutes[] = {
+ PT_GC, ucp_L, /* alpha */
+ PT_PC, ucp_Ll, /* lower */
+ PT_PC, ucp_Lu, /* upper */
+ PT_ALNUM, 0, /* alnum */
+ -1, 0, /* ascii, treat as non-UCP */
+ -1, 1, /* blank, treat as \h */
+ PT_PC, ucp_Cc, /* cntrl */
+ PT_PC, ucp_Nd, /* digit */
+ PT_PXGRAPH, 0, /* graph */
+ PT_PXPRINT, 0, /* print */
+ PT_PXPUNCT, 0, /* punct */
+ PT_PXSPACE, 0, /* space */ /* Xps is POSIX space, but from 8.34 */
+ PT_WORD, 0, /* word */ /* Perl and POSIX space are the same */
+ -1, 0 /* xdigit, treat as non-UCP */
+};
+#define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t)))
+#endif /* SUPPORT_UNICODE */
+
+/* Masks for checking option settings. */
+
+#define PUBLIC_COMPILE_OPTIONS \
+ (PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
+ PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \
+ PCRE2_DOTALL|PCRE2_DUPNAMES|PCRE2_EXTENDED|PCRE2_FIRSTLINE| \
+ PCRE2_MATCH_UNSET_BACKREF|PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C| \
+ PCRE2_NEVER_UCP|PCRE2_NEVER_UTF|PCRE2_NO_AUTO_CAPTURE| \
+ PCRE2_NO_AUTO_POSSESS|PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_NO_START_OPTIMIZE| \
+ PCRE2_NO_UTF_CHECK|PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_USE_OFFSET_LIMIT| \
+ PCRE2_UTF)
+
+/* Compile time error code numbers. They are given names so that they can more
+easily be tracked. When a new number is added, the tables called eint1 and
+eint2 in pcre2posix.c may need to be updated, and a new error text must be
+added to compile_error_texts in pcre2_error.c. */
+
+enum { ERR0 = COMPILE_ERROR_BASE,
+ ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10,
+ ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,
+ ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30,
+ ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40,
+ ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50,
+ ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60,
+ ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70,
+ ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80,
+ ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90 };
+
+/* This is a table of start-of-pattern options such as (*UTF) and settings such
+as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward
+compatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is
+generic and always supported. */
+
+enum { PSO_OPT, /* Value is an option bit */
+ PSO_FLG, /* Value is a flag bit */
+ PSO_NL, /* Value is a newline type */
+ PSO_BSR, /* Value is a \R type */
+ PSO_LIMM, /* Read integer value for match limit */
+ PSO_LIMR }; /* Read integer value for recursion limit */
+
+typedef struct pso {
+ const uint8_t *name;
+ uint16_t length;
+ uint16_t type;
+ uint32_t value;
+} pso;
+
+/* NB: STRING_UTFn_RIGHTPAR contains the length as well */
+
+static pso pso_list[] = {
+ { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF },
+ { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF },
+ { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP },
+ { (uint8_t *)STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET },
+ { (uint8_t *)STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET },
+ { (uint8_t *)STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPT, PCRE2_NO_AUTO_POSSESS },
+ { (uint8_t *)STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPT, PCRE2_NO_DOTSTAR_ANCHOR },
+ { (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT },
+ { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE },
+ { (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 },
+ { (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMR, 0 },
+ { (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR },
+ { (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF },
+ { (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF },
+ { (uint8_t *)STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY },
+ { (uint8_t *)STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF },
+ { (uint8_t *)STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF },
+ { (uint8_t *)STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE }
+};
+
+/* This table is used when converting repeating opcodes into possessified
+versions as a result of an explicit possessive quantifier such as ++. A zero
+value means there is no possessified version - in those cases the item in
+question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT
+because all relevant opcodes are less than that. */
+
+static const uint8_t opcode_possessify[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */
+
+ 0, /* NOTI */
+ OP_POSSTAR, 0, /* STAR, MINSTAR */
+ OP_POSPLUS, 0, /* PLUS, MINPLUS */
+ OP_POSQUERY, 0, /* QUERY, MINQUERY */
+ OP_POSUPTO, 0, /* UPTO, MINUPTO */
+ 0, /* EXACT */
+ 0, 0, 0, 0, /* POS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_POSSTARI, 0, /* STARI, MINSTARI */
+ OP_POSPLUSI, 0, /* PLUSI, MINPLUSI */
+ OP_POSQUERYI, 0, /* QUERYI, MINQUERYI */
+ OP_POSUPTOI, 0, /* UPTOI, MINUPTOI */
+ 0, /* EXACTI */
+ 0, 0, 0, 0, /* POS{STARI,PLUSI,QUERYI,UPTOI} */
+
+ OP_NOTPOSSTAR, 0, /* NOTSTAR, NOTMINSTAR */
+ OP_NOTPOSPLUS, 0, /* NOTPLUS, NOTMINPLUS */
+ OP_NOTPOSQUERY, 0, /* NOTQUERY, NOTMINQUERY */
+ OP_NOTPOSUPTO, 0, /* NOTUPTO, NOTMINUPTO */
+ 0, /* NOTEXACT */
+ 0, 0, 0, 0, /* NOTPOS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_NOTPOSSTARI, 0, /* NOTSTARI, NOTMINSTARI */
+ OP_NOTPOSPLUSI, 0, /* NOTPLUSI, NOTMINPLUSI */
+ OP_NOTPOSQUERYI, 0, /* NOTQUERYI, NOTMINQUERYI */
+ OP_NOTPOSUPTOI, 0, /* NOTUPTOI, NOTMINUPTOI */
+ 0, /* NOTEXACTI */
+ 0, 0, 0, 0, /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */
+
+ OP_TYPEPOSSTAR, 0, /* TYPESTAR, TYPEMINSTAR */
+ OP_TYPEPOSPLUS, 0, /* TYPEPLUS, TYPEMINPLUS */
+ OP_TYPEPOSQUERY, 0, /* TYPEQUERY, TYPEMINQUERY */
+ OP_TYPEPOSUPTO, 0, /* TYPEUPTO, TYPEMINUPTO */
+ 0, /* TYPEEXACT */
+ 0, 0, 0, 0, /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_CRPOSSTAR, 0, /* CRSTAR, CRMINSTAR */
+ OP_CRPOSPLUS, 0, /* CRPLUS, CRMINPLUS */
+ OP_CRPOSQUERY, 0, /* CRQUERY, CRMINQUERY */
+ OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */
+ 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */
+
+ 0, 0, 0, /* CLASS, NCLASS, XCLASS */
+ 0, 0, /* REF, REFI */
+ 0, 0, /* DNREF, DNREFI */
+ 0, 0 /* RECURSE, CALLOUT */
+};
+
+
+#ifdef DEBUG_SHOW_PARSED
+/*************************************************
+* Show the parsed pattern for debugging *
+*************************************************/
+
+/* For debugging the pre-scan, this code, which outputs the parsed data vector,
+can be enabled. */
+
+static void show_parsed(compile_block *cb)
+{
+uint32_t *pptr = cb->parsed_pattern;
+
+for (;;)
+ {
+ int max, min;
+ PCRE2_SIZE offset;
+ uint32_t i;
+ uint32_t length;
+ uint32_t meta_arg = META_DATA(*pptr);
+
+ fprintf(stderr, "+++ %02d %.8x ", (int)(pptr - cb->parsed_pattern), *pptr);
+
+ if (*pptr < META_END)
+ {
+ if (*pptr > 32 && *pptr < 128) fprintf(stderr, "%c", *pptr);
+ pptr++;
+ }
+
+ else switch (META_CODE(*pptr++))
+ {
+ default:
+ fprintf(stderr, "**** OOPS - unknown META value - giving up ****\n");
+ return;
+
+ case META_END:
+ fprintf(stderr, "META_END\n");
+ return;
+
+ case META_CAPTURE:
+ fprintf(stderr, "META_CAPTURE %d", meta_arg);
+ break;
+
+ case META_RECURSE:
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "META_RECURSE %d %zd", meta_arg, offset);
+ break;
+
+ case META_BACKREF:
+ if (meta_arg < 10)
+ offset = cb->small_ref_offset[meta_arg];
+ else
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "META_BACKREF %d %zd", meta_arg, offset);
+ break;
+
+ case META_ESCAPE:
+ if (meta_arg == ESC_P || meta_arg == ESC_p)
+ {
+ uint32_t ptype = *pptr >> 16;
+ uint32_t pvalue = *pptr++ & 0xffff;
+ fprintf(stderr, "META \\%c %d %d", (meta_arg == ESC_P)? 'P':'p',
+ ptype, pvalue);
+ }
+ else
+ {
+ uint32_t cc;
+ /* There's just one escape we might have here that isn't negated in the
+ escapes table. */
+ if (meta_arg == ESC_g) cc = CHAR_g;
+ else for (cc = ESCAPES_FIRST; cc <= ESCAPES_LAST; cc++)
+ {
+ if (meta_arg == (uint32_t)(-escapes[cc - ESCAPES_FIRST])) break;
+ }
+ if (cc > ESCAPES_LAST) cc = CHAR_QUESTION_MARK;
+ fprintf(stderr, "META \\%c", cc);
+ }
+ break;
+
+ case META_MINMAX:
+ min = *pptr++;
+ max = *pptr++;
+ if (max != REPEAT_UNLIMITED)
+ fprintf(stderr, "META {%d,%d}", min, max);
+ else
+ fprintf(stderr, "META {%d,}", min);
+ break;
+
+ case META_MINMAX_QUERY:
+ min = *pptr++;
+ max = *pptr++;
+ if (max != REPEAT_UNLIMITED)
+ fprintf(stderr, "META {%d,%d}?", min, max);
+ else
+ fprintf(stderr, "META {%d,}?", min);
+ break;
+
+ case META_MINMAX_PLUS:
+ min = *pptr++;
+ max = *pptr++;
+ if (max != REPEAT_UNLIMITED)
+ fprintf(stderr, "META {%d,%d}+", min, max);
+ else
+ fprintf(stderr, "META {%d,}+", min);
+ break;
+
+ case META_BIGVALUE: fprintf(stderr, "META_BIGVALUE %.8x", *pptr++); break;
+ case META_CIRCUMFLEX: fprintf(stderr, "META_CIRCUMFLEX"); break;
+ case META_COND_ASSERT: fprintf(stderr, "META_COND_ASSERT"); break;
+ case META_DOLLAR: fprintf(stderr, "META_DOLLAR"); break;
+ case META_DOT: fprintf(stderr, "META_DOT"); break;
+ case META_ASTERISK: fprintf(stderr, "META *"); break;
+ case META_ASTERISK_QUERY: fprintf(stderr, "META *?"); break;
+ case META_ASTERISK_PLUS: fprintf(stderr, "META *+"); break;
+ case META_PLUS: fprintf(stderr, "META +"); break;
+ case META_PLUS_QUERY: fprintf(stderr, "META +?"); break;
+ case META_PLUS_PLUS: fprintf(stderr, "META ++"); break;
+ case META_QUERY: fprintf(stderr, "META ?"); break;
+ case META_QUERY_QUERY: fprintf(stderr, "META ??"); break;
+ case META_QUERY_PLUS: fprintf(stderr, "META ?+"); break;
+
+ case META_ATOMIC: fprintf(stderr, "META (?>"); break;
+ case META_NOCAPTURE: fprintf(stderr, "META (?:"); break;
+ case META_LOOKAHEAD: fprintf(stderr, "META (?="); break;
+ case META_LOOKAHEADNOT: fprintf(stderr, "META (?!"); break;
+ case META_KET: fprintf(stderr, "META )"); break;
+ case META_ALT: fprintf(stderr, "META | %d", meta_arg); break;
+
+ case META_CLASS: fprintf(stderr, "META ["); break;
+ case META_CLASS_NOT: fprintf(stderr, "META [^"); break;
+ case META_CLASS_END: fprintf(stderr, "META ]"); break;
+ case META_CLASS_EMPTY: fprintf(stderr, "META []"); break;
+ case META_CLASS_EMPTY_NOT: fprintf(stderr, "META [^]"); break;
+
+ case META_RANGE_LITERAL: fprintf(stderr, "META - (literal)"); break;
+ case META_RANGE_ESCAPED: fprintf(stderr, "META - (escaped)"); break;
+
+ case META_POSIX: fprintf(stderr, "META_POSIX %d", *pptr++); break;
+ case META_POSIX_NEG: fprintf(stderr, "META_POSIX_NEG %d", *pptr++); break;
+
+ case META_ACCEPT: fprintf(stderr, "META (*ACCEPT)"); break;
+ case META_COMMIT: fprintf(stderr, "META (*COMMIT)"); break;
+ case META_FAIL: fprintf(stderr, "META (*FAIL)"); break;
+ case META_PRUNE: fprintf(stderr, "META (*PRUNE)"); break;
+ case META_SKIP: fprintf(stderr, "META (*SKIP)"); break;
+ case META_THEN: fprintf(stderr, "META (*THEN)"); break;
+
+ case META_OPTIONS: fprintf(stderr, "META_OPTIONS 0x%02x", *pptr++); break;
+
+ case META_LOOKBEHIND:
+ fprintf(stderr, "META (?<= %d offset=", meta_arg);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ case META_LOOKBEHINDNOT:
+ fprintf(stderr, "META (?<! %d offset=", meta_arg);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ case META_CALLOUT_NUMBER:
+ fprintf(stderr, "META (?C%d) next=%d/%d", pptr[2], pptr[0],
+ pptr[1]);
+ pptr += 3;
+ break;
+
+ case META_CALLOUT_STRING:
+ {
+ uint32_t patoffset = *pptr++; /* Offset of next pattern item */
+ uint32_t patlength = *pptr++; /* Length of next pattern item */
+ fprintf(stderr, "META (?Cstring) length=%d offset=", *pptr++);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd next=%d/%d", offset, patoffset, patlength);
+ }
+ break;
+
+ case META_RECURSE_BYNAME:
+ fprintf(stderr, "META (?(&name) length=%d offset=", *pptr++);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ case META_BACKREF_BYNAME:
+ fprintf(stderr, "META_BACKREF_BYNAME length=%d offset=", *pptr++);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ case META_COND_NUMBER:
+ fprintf(stderr, "META_COND_NUMBER %d offset=", pptr[SIZEOFFSET]);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ pptr++;
+ break;
+
+ case META_COND_DEFINE:
+ fprintf(stderr, "META (?(DEFINE) offset=");
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ case META_COND_VERSION:
+ fprintf(stderr, "META (?(VERSION%s", (*pptr++ == 0)? "=" : ">=");
+ fprintf(stderr, "%d.", *pptr++);
+ fprintf(stderr, "%d)", *pptr++);
+ break;
+
+ case META_COND_NAME:
+ fprintf(stderr, "META (?(<name>) length=%d offset=", *pptr++);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ case META_COND_RNAME:
+ fprintf(stderr, "META (?(R&name) length=%d offset=", *pptr++);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ /* This is kept as a name, because it might be. */
+
+ case META_COND_RNUMBER:
+ fprintf(stderr, "META (?(Rnumber) length=%d offset=", *pptr++);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
+ case META_MARK:
+ fprintf(stderr, "META (*MARK:");
+ goto SHOWARG;
+
+ case META_PRUNE_ARG:
+ fprintf(stderr, "META (*PRUNE:");
+ goto SHOWARG;
+
+ case META_SKIP_ARG:
+ fprintf(stderr, "META (*SKIP:");
+ goto SHOWARG;
+
+ case META_THEN_ARG:
+ fprintf(stderr, "META (*THEN:");
+ SHOWARG:
+ length = *pptr++;
+ for (i = 0; i < length; i++)
+ {
+ uint32_t cc = *pptr++;
+ if (cc > 32 && cc < 128) fprintf(stderr, "%c", cc);
+ else fprintf(stderr, "\\x{%x}", cc);
+ }
+ fprintf(stderr, ") length=%u", length);
+ break;
+ }
+ fprintf(stderr, "\n");
+ }
+return;
+}
+#endif /* DEBUG_SHOW_PARSED */
+
+
+
+/*************************************************
+* Copy compiled code *
+*************************************************/
+
+/* Compiled JIT code cannot be copied, so the new compiled block has no
+associated JIT data. */
+
+PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
+pcre2_code_copy(const pcre2_code *code)
+{
+PCRE2_SIZE* ref_count;
+pcre2_code *newcode;
+
+if (code == NULL) return NULL;
+newcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);
+if (newcode == NULL) return NULL;
+memcpy(newcode, code, code->blocksize);
+newcode->executable_jit = NULL;
+
+/* If the code is one that has been deserialized, increment the reference count
+in the decoded tables. */
+
+if ((code->flags & PCRE2_DEREF_TABLES) != 0)
+ {
+ ref_count = (PCRE2_SIZE *)(code->tables + tables_length);
+ (*ref_count)++;
+ }
+
+return newcode;
+}
+
+
+
+/*************************************************
+* Copy compiled code and character tables *
+*************************************************/
+
+/* Compiled JIT code cannot be copied, so the new compiled block has no
+associated JIT data. This version of code_copy also makes a separate copy of
+the character tables. */
+
+PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
+pcre2_code_copy_with_tables(const pcre2_code *code)
+{
+PCRE2_SIZE* ref_count;
+pcre2_code *newcode;
+uint8_t *newtables;
+
+if (code == NULL) return NULL;
+newcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);
+if (newcode == NULL) return NULL;
+memcpy(newcode, code, code->blocksize);
+newcode->executable_jit = NULL;
+
+newtables = code->memctl.malloc(tables_length + sizeof(PCRE2_SIZE),
+ code->memctl.memory_data);
+if (newtables == NULL)
+ {
+ code->memctl.free((void *)newcode, code->memctl.memory_data);
+ return NULL;
+ }
+memcpy(newtables, code->tables, tables_length);
+ref_count = (PCRE2_SIZE *)(newtables + tables_length);
+*ref_count = 1;
+
+newcode->tables = newtables;
+newcode->flags |= PCRE2_DEREF_TABLES;
+return newcode;
+}
+
+
+
+/*************************************************
+* Free compiled code *
+*************************************************/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_code_free(pcre2_code *code)
+{
+PCRE2_SIZE* ref_count;
+
+if (code != NULL)
+ {
+ if (code->executable_jit != NULL)
+ PRIV(jit_free)(code->executable_jit, &code->memctl);
+
+ if ((code->flags & PCRE2_DEREF_TABLES) != 0)
+ {
+ /* Decoded tables belong to the codes after deserialization, and they must
+ be freed when there are no more reference to them. The *ref_count should
+ always be > 0. */
+
+ ref_count = (PCRE2_SIZE *)(code->tables + tables_length);
+ if (*ref_count > 0)
+ {
+ (*ref_count)--;
+ if (*ref_count == 0)
+ code->memctl.free((void *)code->tables, code->memctl.memory_data);
+ }
+ }
+
+ code->memctl.free(code, code->memctl.memory_data);
+ }
+}
+
+
+
+/*************************************************
+* Read a number, possibly signed *
+*************************************************/
+
+/* This function is used to read numbers in the pattern. The initial pointer
+must be the sign or first digit of the number. When relative values (introduced
+by + or -) are allowed, they are relative group numbers, and the result must be
+greater than zero.
+
+Arguments:
+ ptrptr points to the character pointer variable
+ ptrend points to the end of the input string
+ allow_sign if < 0, sign not allowed; if >= 0, sign is relative to this
+ max_value the largest number allowed
+ max_error the error to give for an over-large number
+ intptr where to put the result
+ errcodeptr where to put an error code
+
+Returns: TRUE - a number was read
+ FALSE - errorcode == 0 => no number was found
+ errorcode != 0 => an error occurred
+*/
+
+static BOOL
+read_number(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, int32_t allow_sign,
+ uint32_t max_value, uint32_t max_error, int *intptr, int *errorcodeptr)
+{
+int sign = 0;
+uint32_t n = 0;
+PCRE2_SPTR ptr = *ptrptr;
+BOOL yield = FALSE;
+
+*errorcodeptr = 0;
+
+if (allow_sign >= 0 && ptr < ptrend)
+ {
+ if (*ptr == CHAR_PLUS)
+ {
+ sign = +1;
+ max_value -= allow_sign;
+ ptr++;
+ }
+ else if (*ptr == CHAR_MINUS)
+ {
+ sign = -1;
+ ptr++;
+ }
+ }
+
+if (ptr >= ptrend || !IS_DIGIT(*ptr)) return FALSE;
+while (ptr < ptrend && IS_DIGIT(*ptr))
+ {
+ n = n * 10 + *ptr++ - CHAR_0;
+ if (n > max_value)
+ {
+ *errorcodeptr = max_error;
+ goto EXIT;
+ }
+ }
+
+if (allow_sign >= 0 && sign != 0)
+ {
+ if (n == 0)
+ {
+ *errorcodeptr = ERR26; /* +0 and -0 are not allowed */
+ goto EXIT;
+ }
+
+ if (sign > 0) n += allow_sign;
+ else if ((int)n > allow_sign)
+ {
+ *errorcodeptr = ERR15; /* Non-existent subpattern */
+ goto EXIT;
+ }
+ else n = allow_sign + 1 - n;
+ }
+
+yield = TRUE;
+
+EXIT:
+*intptr = n;
+*ptrptr = ptr;
+return yield;
+}
+
+
+
+/*************************************************
+* Read repeat counts *
+*************************************************/
+
+/* Read an item of the form {n,m} and return the values if non-NULL pointers
+are supplied. Repeat counts must be less than 65536 (MAX_REPEAT_COUNT); a
+larger value is used for "unlimited". We have to use signed arguments for
+read_number() because it is capable of returning a signed value.
+
+Arguments:
+ ptrptr points to pointer to character after'{'
+ ptrend pointer to end of input
+ minp if not NULL, pointer to int for min
+ maxp if not NULL, pointer to int for max (-1 if no max)
+ returned as -1 if no max
+ errorcodeptr points to error code variable
+
+Returns: FALSE if not a repeat quantifier, errorcode set zero
+ FALSE on error, with errorcode set non-zero
+ TRUE on success, with pointer updated to point after '}'
+*/
+
+static BOOL
+read_repeat_counts(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *minp,
+ uint32_t *maxp, int *errorcodeptr)
+{
+PCRE2_SPTR p = *ptrptr;
+BOOL yield = FALSE;
+int32_t min = 0;
+int32_t max = REPEAT_UNLIMITED; /* This value is larger than MAX_REPEAT_COUNT */
+
+/* NB read_number() initializes the error code to zero. The only error is for a
+number that is too big. */
+
+if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr))
+ goto EXIT;
+
+if (p >= ptrend) goto EXIT;
+
+if (*p == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ p++;
+ max = min;
+ }
+
+else
+ {
+ if (*p++ != CHAR_COMMA || p >= ptrend) goto EXIT;
+ if (*p != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max,
+ errorcodeptr) || p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET)
+ goto EXIT;
+ if (max < min)
+ {
+ *errorcodeptr = ERR4;
+ goto EXIT;
+ }
+ }
+ p++;
+ }
+
+yield = TRUE;
+if (minp != NULL) *minp = (uint32_t)min;
+if (maxp != NULL) *maxp = (uint32_t)max;
+
+/* Update the pattern pointer on success, or after an error, but not when
+the result is "not a repeat quantifier". */
+
+EXIT:
+if (yield || *errorcodeptr != 0) *ptrptr = p;
+return yield;
+
+
+
+}
+
+
+
+/*************************************************
+* Handle escapes *
+*************************************************/
+
+/* This function is called when a \ has been encountered. It either returns a
+positive value for a simple escape such as \d, or 0 for a data character, which
+is placed in chptr. A backreference to group n is returned as negative n. On
+entry, ptr is pointing at the character after \. On exit, it points after the
+final code unit of the escape sequence.
+
+This function is also called from pcre2_substitute() to handle escape sequences
+in replacement strings. In this case, the cb argument is NULL, and in the case
+of escapes that have further processing, only sequences that define a data
+character are recognised. The isclass argument is not relevant; the options
+argument is the final value of the compiled pattern's options.
+
+Arguments:
+ ptrptr points to the input position pointer
+ ptrend points to the end of the input
+ chptr points to a returned data character
+ errorcodeptr points to the errorcode variable (containing zero)
+ options the current options bits
+ isclass TRUE if inside a character class
+ cb compile data block
+
+Returns: zero => a data character
+ positive => a special escape sequence
+ negative => a numerical back reference
+ on error, errorcodeptr is set non-zero
+*/
+
+int
+PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr,
+ int *errorcodeptr, uint32_t options, BOOL isclass, compile_block *cb)
+{
+BOOL utf = (options & PCRE2_UTF) != 0;
+PCRE2_SPTR ptr = *ptrptr;
+uint32_t c, cc;
+int escape = 0;
+int i;
+
+/* If backslash is at the end of the string, it's an error. */
+
+if (ptr >= ptrend)
+ {
+ *errorcodeptr = ERR1;
+ return 0;
+ }
+
+GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
+*errorcodeptr = 0; /* Be optimistic */
+
+/* Non-alphanumerics are literals, so we just leave the value in c. An initial
+value test saves a memory lookup for code points outside the alphanumeric
+range. Otherwise, do a table lookup. A non-zero result is something that can be
+returned immediately. Otherwise further processing is required. */
+
+if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {} /* Definitely literal */
+
+else if ((i = escapes[c - ESCAPES_FIRST]) != 0)
+ {
+ if (i > 0) c = (uint32_t)i; else /* Positive is a data character */
+ {
+ escape = -i; /* Else return a special escape */
+ if (cb != NULL && (escape == ESC_P || escape == ESC_p || escape == ESC_X))
+ cb->external_flags |= PCRE2_HASBKPORX; /* Note \P, \p, or \X */
+ }
+ }
+
+/* Escapes that need further processing, including those that are unknown.
+When called from pcre2_substitute(), only \c, \o, and \x are recognized (and \u
+when BSUX is set). */
+
+else
+ {
+ PCRE2_SPTR oldptr;
+ BOOL overflow;
+ int s;
+
+ /* Filter calls from pcre2_substitute(). */
+
+ if (cb == NULL && c != CHAR_c && c != CHAR_o && c != CHAR_x &&
+ (c != CHAR_u || (options & PCRE2_ALT_BSUX) != 0))
+ {
+ *errorcodeptr = ERR3;
+ return 0;
+ }
+
+ switch (c)
+ {
+ /* A number of Perl escapes are not handled by PCRE. We give an explicit
+ error. */
+
+ case CHAR_l:
+ case CHAR_L:
+ *errorcodeptr = ERR37;
+ break;
+
+ /* \u is unrecognized when PCRE2_ALT_BSUX is not set. When it is treated
+ specially, \u must be followed by four hex digits. Otherwise it is a
+ lowercase u letter. */
+
+ case CHAR_u:
+ if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; else
+ {
+ uint32_t xc;
+ if (ptrend - ptr < 4) break; /* Less than 4 chars */
+ if ((cc = XDIGIT(ptr[0])) == 0xff) break; /* Not a hex digit */
+ if ((xc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */
+ cc = (cc << 4) | xc;
+ if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */
+ cc = (cc << 4) | xc;
+ if ((xc = XDIGIT(ptr[3])) == 0xff) break; /* Not a hex digit */
+ c = (cc << 4) | xc;
+ ptr += 4;
+ if (utf)
+ {
+ if (c > 0x10ffffU) *errorcodeptr = ERR77;
+ else if (c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ }
+ else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77;
+ }
+ break;
+
+ /* \U is unrecognized unless PCRE2_ALT_BSUX is set, in which case it is an
+ upper case letter. */
+
+ case CHAR_U:
+ if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37;
+ break;
+
+ /* In a character class, \g is just a literal "g". Outside a character
+ class, \g must be followed by one of a number of specific things:
+
+ (1) A number, either plain or braced. If positive, it is an absolute
+ backreference. If negative, it is a relative backreference. This is a Perl
+ 5.10 feature.
+
+ (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
+ is part of Perl's movement towards a unified syntax for back references. As
+ this is synonymous with \k{name}, we fudge it up by pretending it really
+ was \k{name}.
+
+ (3) For Oniguruma compatibility we also support \g followed by a name or a
+ number either in angle brackets or in single quotes. However, these are
+ (possibly recursive) subroutine calls, _not_ backreferences. We return
+ the ESC_g code.
+
+ Summary: Return a negative number for a numerical back reference, ESC_k for
+ a named back reference, and ESC_g for a named or numbered subroutine call.
+ */
+
+ case CHAR_g:
+ if (isclass) break;
+
+ if (ptr >= ptrend)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+
+ if (*ptr == CHAR_LESS_THAN_SIGN || *ptr == CHAR_APOSTROPHE)
+ {
+ escape = ESC_g;
+ break;
+ }
+
+ /* If there is a brace delimiter, try to read a numerical reference. If
+ there isn't one, assume we have a name and treat it as \k. */
+
+ if (*ptr == CHAR_LEFT_CURLY_BRACKET)
+ {
+ PCRE2_SPTR p = ptr + 1;
+ if (!read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s,
+ errorcodeptr))
+ {
+ if (*errorcodeptr == 0) escape = ESC_k; /* No number found */
+ break;
+ }
+ if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+ ptr = p + 1;
+ }
+
+ /* Read an undelimited number */
+
+ else
+ {
+ if (!read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s,
+ errorcodeptr))
+ {
+ if (*errorcodeptr == 0) *errorcodeptr = ERR57; /* No number found */
+ break;
+ }
+ }
+
+ if (s <= 0)
+ {
+ *errorcodeptr = ERR15;
+ break;
+ }
+
+ escape = -s;
+ break;
+
+ /* The handling of escape sequences consisting of a string of digits
+ starting with one that is not zero is not straightforward. Perl has changed
+ over the years. Nowadays \g{} for backreferences and \o{} for octal are
+ recommended to avoid the ambiguities in the old syntax.
+
+ Outside a character class, the digits are read as a decimal number. If the
+ number is less than 10, or if there are that many previous extracting left
+ brackets, it is a back reference. Otherwise, up to three octal digits are
+ read to form an escaped character code. Thus \123 is likely to be octal 123
+ (cf \0123, which is octal 012 followed by the literal 3).
+
+ Inside a character class, \ followed by a digit is always either a literal
+ 8 or 9 or an octal number. */
+
+ case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:
+ case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+
+ if (!isclass)
+ {
+ oldptr = ptr;
+ ptr--; /* Back to the digit */
+ if (!read_number(&ptr, ptrend, -1, INT_MAX/10 - 1, ERR61, &s,
+ errorcodeptr))
+ break;
+
+ /* \1 to \9 are always back references. \8x and \9x are too; \1x to \7x
+ are octal escapes if there are not that many previous captures. */
+
+ if (s < 10 || oldptr[-1] >= CHAR_8 || s <= (int)cb->bracount)
+ {
+ if (s > (int)MAX_GROUP_NUMBER) *errorcodeptr = ERR61;
+ else escape = -s; /* Indicates a back reference */
+ break;
+ }
+ ptr = oldptr; /* Put the pointer back and fall through */
+ }
+
+ /* Handle a digit following \ when the number is not a back reference, or
+ we are within a character class. If the first digit is 8 or 9, Perl used to
+ generate a binary zero and then treat the digit as a following literal. At
+ least by Perl 5.18 this changed so as not to insert the binary zero. */
+
+ if (c >= CHAR_8) break;
+
+ /* Fall through with a digit less than 8 */
+
+ /* \0 always starts an octal number, but we may drop through to here with a
+ larger first octal digit. The original code used just to take the least
+ significant 8 bits of octal numbers (I think this is what early Perls used
+ to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode,
+ but no more than 3 octal digits. */
+
+ case CHAR_0:
+ c -= CHAR_0;
+ while(i++ < 2 && ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7)
+ c = c * 8 + *ptr++ - CHAR_0;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (!utf && c > 0xff) *errorcodeptr = ERR51;
+#endif
+ break;
+
+ /* \o is a relatively new Perl feature, supporting a more general way of
+ specifying character codes in octal. The only supported form is \o{ddd}. */
+
+ case CHAR_o:
+ if (ptr >= ptrend || *ptr++ != CHAR_LEFT_CURLY_BRACKET)
+ {
+ ptr--;
+ *errorcodeptr = ERR55;
+ }
+ else if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)
+ *errorcodeptr = ERR78;
+ else
+ {
+ c = 0;
+ overflow = FALSE;
+ while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7)
+ {
+ cc = *ptr++;
+ if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
+#if PCRE2_CODE_UNIT_WIDTH == 32
+ if (c >= 0x20000000l) { overflow = TRUE; break; }
+#endif
+ c = (c << 3) + (cc - CHAR_0);
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+ if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
+#endif
+ }
+ if (overflow)
+ {
+ while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;
+ *errorcodeptr = ERR34;
+ }
+ else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff)
+ {
+ ptr--;
+ *errorcodeptr = ERR73;
+ }
+ }
+ else
+ {
+ ptr--;
+ *errorcodeptr = ERR64;
+ }
+ }
+ break;
+
+ /* \x is complicated. When PCRE2_ALT_BSUX is set, \x must be followed by
+ two hexadecimal digits. Otherwise it is a lowercase x letter. */
+
+ case CHAR_x:
+ if ((options & PCRE2_ALT_BSUX) != 0)
+ {
+ uint32_t xc;
+ if (ptrend - ptr < 2) break; /* Less than 2 characters */
+ if ((cc = XDIGIT(ptr[0])) == 0xff) break; /* Not a hex digit */
+ if ((xc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */
+ c = (cc << 4) | xc;
+ ptr += 2;
+ } /* End PCRE2_ALT_BSUX handling */
+
+ /* Handle \x in Perl's style. \x{ddd} is a character number which can be
+ greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex
+ digits. If not, { used to be treated as a data character. However, Perl
+ seems to read hex digits up to the first non-such, and ignore the rest, so
+ that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE
+ now gives an error. */
+
+ else
+ {
+ if (ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET)
+ {
+ if (++ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ *errorcodeptr = ERR78;
+ break;
+ }
+ c = 0;
+ overflow = FALSE;
+
+ while (ptr < ptrend && (cc = XDIGIT(*ptr)) != 0xff)
+ {
+ ptr++;
+ if (c == 0 && cc == 0) continue; /* Leading zeroes */
+#if PCRE2_CODE_UNIT_WIDTH == 32
+ if (c >= 0x10000000l) { overflow = TRUE; break; }
+#endif
+ c = (c << 4) | cc;
+ if ((utf && c > 0x10ffffU) || (!utf && c > MAX_NON_UTF_CHAR))
+ {
+ overflow = TRUE;
+ break;
+ }
+ }
+
+ if (overflow)
+ {
+ while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++;
+ *errorcodeptr = ERR34;
+ }
+ else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff)
+ {
+ ptr--;
+ *errorcodeptr = ERR73;
+ }
+ }
+
+ /* If the sequence of hex digits does not end with '}', give an error.
+ We used just to recognize this construct and fall through to the normal
+ \x handling, but nowadays Perl gives an error, which seems much more
+ sensible, so we do too. */
+
+ else
+ {
+ ptr--;
+ *errorcodeptr = ERR67;
+ }
+ } /* End of \x{} processing */
+
+ /* Read a up to two hex digits after \x */
+
+ else
+ {
+ c = 0;
+ if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */
+ ptr++;
+ c = cc;
+ if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */
+ ptr++;
+ c = (c << 4) | cc;
+ } /* End of \xdd handling */
+ } /* End of Perl-style \x handling */
+ break;
+
+ /* The handling of \c is different in ASCII and EBCDIC environments. In an
+ ASCII (or Unicode) environment, an error is given if the character
+ following \c is not a printable ASCII character. Otherwise, the following
+ character is upper-cased if it is a letter, and after that the 0x40 bit is
+ flipped. The result is the value of the escape.
+
+ In an EBCDIC environment the handling of \c is compatible with the
+ specification in the perlebcdic document. The following character must be
+ a letter or one of small number of special characters. These provide a
+ means of defining the character values 0-31.
+
+ For testing the EBCDIC handling of \c in an ASCII environment, recognize
+ the EBCDIC value of 'c' explicitly. */
+
+#if defined EBCDIC && 'a' != 0x81
+ case 0x83:
+#else
+ case CHAR_c:
+#endif
+ if (ptr >= ptrend)
+ {
+ *errorcodeptr = ERR2;
+ break;
+ }
+ c = *ptr;
+ if (c >= CHAR_a && c <= CHAR_z) c = UPPER_CASE(c);
+
+ /* Handle \c in an ASCII/Unicode environment. */
+
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (c < 32 || c > 126) /* Excludes all non-printable ASCII */
+ {
+ *errorcodeptr = ERR68;
+ break;
+ }
+ c ^= 0x40;
+
+ /* Handle \c in an EBCDIC environment. The special case \c? is converted to
+ 255 (0xff) or 95 (0x5f) if other character suggest we are using th POSIX-BC
+ encoding. (This is the way Perl indicates that it handles \c?.) The other
+ valid sequences correspond to a list of specific characters. */
+
+#else
+ if (c == CHAR_QUESTION_MARK)
+ c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
+ else
+ {
+ for (i = 0; i < 32; i++)
+ {
+ if (c == ebcdic_escape_c[i]) break;
+ }
+ if (i < 32) c = i; else *errorcodeptr = ERR68;
+ }
+#endif /* EBCDIC */
+
+ ptr++;
+ break;
+
+ /* Any other alphanumeric following \ is an error. Perl gives an error only
+ if in warning mode, but PCRE doesn't have a warning mode. */
+
+ default:
+ *errorcodeptr = ERR3;
+ *ptrptr = ptr - 1; /* Point to the character at fault */
+ return 0;
+ }
+ }
+
+/* Perl supports \N{name} for character names, as well as plain \N for "not
+newline". PCRE does not support \N{name}. However, it does support
+quantification such as \N{2,3}. */
+
+if (escape == ESC_N && ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET &&
+ ptrend - ptr > 2)
+ {
+ PCRE2_SPTR p = ptr + 1;
+ if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) &&
+ *errorcodeptr == 0)
+ *errorcodeptr = ERR37;
+ }
+
+/* Set the pointer to the next character before returning. */
+
+*ptrptr = ptr;
+*chptr = c;
+return escape;
+}
+
+
+
+#ifdef SUPPORT_UNICODE
+/*************************************************
+* Handle \P and \p *
+*************************************************/
+
+/* This function is called after \P or \p has been encountered, provided that
+PCRE2 is compiled with support for UTF and Unicode properties. On entry, the
+contents of ptrptr are pointing after the P or p. On exit, it is left pointing
+after the final code unit of the escape sequence.
+
+Arguments:
+ ptrptr the pattern position pointer
+ negptr a boolean that is set TRUE for negation else FALSE
+ ptypeptr an unsigned int that is set to the type value
+ pdataptr an unsigned int that is set to the detailed property value
+ errorcodeptr the error code variable
+ cb the compile data
+
+Returns: TRUE if the type value was found, or FALSE for an invalid type
+*/
+
+static BOOL
+get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, uint16_t *ptypeptr,
+ uint16_t *pdataptr, int *errorcodeptr, compile_block *cb)
+{
+PCRE2_UCHAR c;
+PCRE2_SIZE i, bot, top;
+PCRE2_SPTR ptr = *ptrptr;
+PCRE2_UCHAR name[32];
+
+if (ptr >= cb->end_pattern) goto ERROR_RETURN;
+c = *ptr++;
+*negptr = FALSE;
+
+/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
+negation. */
+
+if (c == CHAR_LEFT_CURLY_BRACKET)
+ {
+ if (ptr >= cb->end_pattern) goto ERROR_RETURN;
+ if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ *negptr = TRUE;
+ ptr++;
+ }
+ for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++)
+ {
+ if (ptr >= cb->end_pattern) goto ERROR_RETURN;
+ c = *ptr++;
+ if (c == CHAR_NULL) goto ERROR_RETURN;
+ if (c == CHAR_RIGHT_CURLY_BRACKET) break;
+ name[i] = c;
+ }
+ if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
+ name[i] = 0;
+ }
+
+/* Otherwise there is just one following character, which must be an ASCII
+letter. */
+
+else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0)
+ {
+ name[0] = c;
+ name[1] = 0;
+ }
+else goto ERROR_RETURN;
+
+*ptrptr = ptr;
+
+/* Search for a recognized property name using binary chop. */
+
+bot = 0;
+top = PRIV(utt_size);
+
+while (bot < top)
+ {
+ int r;
+ i = (bot + top) >> 1;
+ r = PRIV(strcmp_c8)(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
+ if (r == 0)
+ {
+ *ptypeptr = PRIV(utt)[i].type;
+ *pdataptr = PRIV(utt)[i].value;
+ return TRUE;
+ }
+ if (r > 0) bot = i + 1; else top = i;
+ }
+*errorcodeptr = ERR47; /* Unrecognized name */
+return FALSE;
+
+ERROR_RETURN: /* Malformed \P or \p */
+*errorcodeptr = ERR46;
+*ptrptr = ptr;
+return FALSE;
+}
+#endif
+
+
+
+/*************************************************
+* Check for POSIX class syntax *
+*************************************************/
+
+/* This function is called when the sequence "[:" or "[." or "[=" is
+encountered in a character class. It checks whether this is followed by a
+sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
+reach an unescaped ']' without the special preceding character, return FALSE.
+
+Originally, this function only recognized a sequence of letters between the
+terminators, but it seems that Perl recognizes any sequence of characters,
+though of course unknown POSIX names are subsequently rejected. Perl gives an
+"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
+didn't consider this to be a POSIX class. Likewise for [:1234:].
+
+The problem in trying to be exactly like Perl is in the handling of escapes. We
+have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
+class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
+below handles the special cases \\ and \], but does not try to do any other
+escape processing. This makes it different from Perl for cases such as
+[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does
+not recognize "l\ower". This is a lesser evil than not diagnosing bad classes
+when Perl does, I think.
+
+A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
+It seems that the appearance of a nested POSIX class supersedes an apparent
+external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
+a digit. This is handled by returning FALSE if the start of a new group with
+the same terminator is encountered, since the next closing sequence must close
+the nested group, not the outer one.
+
+In Perl, unescaped square brackets may also appear as part of class names. For
+example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
+[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
+seem right at all. PCRE does not allow closing square brackets in POSIX class
+names.
+
+Arguments:
+ ptr pointer to the character after the initial [ (colon, dot, equals)
+ ptrend pointer to the end of the pattern
+ endptr where to return a pointer to the terminating ':', '.', or '='
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+check_posix_syntax(PCRE2_SPTR ptr, PCRE2_SPTR ptrend, PCRE2_SPTR *endptr)
+{
+PCRE2_UCHAR terminator; /* Don't combine these lines; the Solaris cc */
+terminator = *ptr++; /* compiler warns about "non-constant" initializer. */
+
+for (; ptrend - ptr >= 2; ptr++)
+ {
+ if (*ptr == CHAR_BACKSLASH &&
+ (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET || ptr[1] == CHAR_BACKSLASH))
+ ptr++;
+
+ else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||
+ *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
+
+ else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+ {
+ *endptr = ptr;
+ return TRUE;
+ }
+ }
+
+return FALSE;
+}
+
+
+
+/*************************************************
+* Check POSIX class name *
+*************************************************/
+
+/* This function is called to check the name given in a POSIX-style class entry
+such as [:alnum:].
+
+Arguments:
+ ptr points to the first letter
+ len the length of the name
+
+Returns: a value representing the name, or -1 if unknown
+*/
+
+static int
+check_posix_name(PCRE2_SPTR ptr, int len)
+{
+const char *pn = posix_names;
+int yield = 0;
+while (posix_name_lengths[yield] != 0)
+ {
+ if (len == posix_name_lengths[yield] &&
+ PRIV(strncmp_c8)(ptr, pn, (unsigned int)len) == 0) return yield;
+ pn += posix_name_lengths[yield] + 1;
+ yield++;
+ }
+return -1;
+}
+
+
+
+/*************************************************
+* Read a subpattern or VERB name *
+*************************************************/
+
+/* This function is called from parse_regex() below whenever it needs to read
+the name of a subpattern or a (*VERB). The initial pointer must be to the
+character before the name. If that character is '*' we are reading a verb name.
+The pointer is updated to point after the name, for a VERB, or after tha name's
+terminator for a subpattern name. Returning both the offset and the name
+pointer is redundant information, but some callers use one and some the other,
+so it is simplest just to return both.
+
+Arguments:
+ ptrptr points to the character pointer variable
+ ptrend points to the end of the input string
+ terminator the terminator of a subpattern name must be this
+ offsetptr where to put the offset from the start of the pattern
+ nameptr where to put a pointer to the name in the input
+ namelenptr where to put the length of the name
+ errcodeptr where to put an error code
+ cb pointer to the compile data block
+
+Returns: TRUE if a name was read
+ FALSE otherwise, with error code set
+*/
+
+static BOOL
+read_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t terminator,
+ PCRE2_SIZE *offsetptr, PCRE2_SPTR *nameptr, uint32_t *namelenptr,
+ int *errorcodeptr, compile_block *cb)
+{
+PCRE2_SPTR ptr = *ptrptr;
+BOOL is_verb = (*ptr == CHAR_ASTERISK);
+uint32_t namelen = 0;
+uint32_t ctype = is_verb? ctype_letter : ctype_word;
+
+if (++ptr >= ptrend)
+ {
+ *errorcodeptr = is_verb? ERR60: /* Verb not recognized or malformed */
+ ERR62; /* Subpattern name expected */
+ goto FAILED;
+ }
+
+*nameptr = ptr;
+*offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern);
+
+if (IS_DIGIT(*ptr))
+ {
+ *errorcodeptr = ERR44; /* Group name must not start with digit */
+ goto FAILED;
+ }
+
+while (ptr < ptrend && MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype) != 0)
+ {
+ ptr++;
+ namelen++;
+ if (namelen > MAX_NAME_SIZE)
+ {
+ *errorcodeptr = ERR48;
+ goto FAILED;
+ }
+ }
+
+/* Subpattern names must not be empty, and their terminator is checked here.
+(What follows a verb name is checked separately.) */
+
+if (!is_verb)
+ {
+ if (namelen == 0)
+ {
+ *errorcodeptr = ERR62; /* Subpattern name expected */
+ goto FAILED;
+ }
+ if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
+ ptr++;
+ }
+
+*namelenptr = namelen;
+*ptrptr = ptr;
+return TRUE;
+
+FAILED:
+*ptrptr = ptr;
+return FALSE;
+}
+
+
+
+/*************************************************
+* Manage callouts at start of cycle *
+*************************************************/
+
+/* At the start of a new item in parse_regex() we are able to record the
+details of the previous item in a prior callout, and also to set up an
+automatic callout if enabled. Avoid having two adjacent automatic callouts,
+which would otherwise happen for items such as \Q that contribute nothing to
+the parsed pattern.
+
+Arguments:
+ ptr current pattern pointer
+ pcalloutptr points to a pointer to previous callout, or NULL
+ options the compiling options
+ parsed_pattern the parsed pattern pointer
+ cb compile block
+
+Returns: possibly updated parsed_pattern pointer.
+*/
+
+static uint32_t *
+manage_callouts(PCRE2_SPTR ptr, uint32_t **pcalloutptr, uint32_t options,
+ uint32_t *parsed_pattern, compile_block *cb)
+{
+uint32_t *previous_callout = *pcalloutptr;
+
+if (previous_callout != NULL) previous_callout[2] = ptr - cb->start_pattern -
+ (PCRE2_SIZE)previous_callout[1];
+
+if ((options & PCRE2_AUTO_CALLOUT) == 0) previous_callout = NULL; else
+ {
+ if (previous_callout == NULL ||
+ previous_callout != parsed_pattern - 4 ||
+ previous_callout[3] != 255)
+ {
+ previous_callout = parsed_pattern; /* Set up new automatic callout */
+ parsed_pattern += 4;
+ previous_callout[0] = META_CALLOUT_NUMBER;
+ previous_callout[2] = 0;
+ previous_callout[3] = 255;
+ }
+ previous_callout[1] = (uint32_t)(ptr - cb->start_pattern);
+ }
+
+*pcalloutptr = previous_callout;
+return parsed_pattern;
+}
+
+
+
+/*************************************************
+* Parse regex and identify named groups *
+*************************************************/
+
+/* This function is called first of all. It scans the pattern and does two
+things: (1) It identifies capturing groups and makes a table of named capturing
+groups so that information about them is fully available to both the compiling
+scans. (2) It writes a parsed version of the pattern with comments omitted and
+escapes processed into the parsed_pattern vector.
+
+Arguments:
+ ptr points to the start of the pattern
+ options compiling dynamic options (may change during the scan)
+ has_lookbehind points to a boolean, set TRUE if a lookbehind is found
+ cb pointer to the compile data block
+
+Returns: zero on success or a non-zero error code, with the
+ error offset placed in the cb field
+*/
+
+/* A structure and some flags for dealing with nested groups. */
+
+typedef struct nest_save {
+ uint16_t nest_depth;
+ uint16_t reset_group;
+ uint16_t max_group;
+ uint16_t flags;
+} nest_save;
+
+#define NSF_RESET 0x0001u
+#define NSF_EXTENDED 0x0002u
+#define NSF_DUPNAMES 0x0004u
+#define NSF_CONDASSERT 0x0008u
+
+/* States used for analyzing ranges in character classes. The two OK values
+must be last. */
+
+enum { RANGE_NO, RANGE_STARTED, RANGE_OK_ESCAPED, RANGE_OK_LITERAL };
+
+/* Only in 32-bit mode can there be literals > META_END. A macros encapsulates
+the storing of literal values in the parsed pattern. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 32
+#define PARSED_LITERAL(c, p) \
+ { \
+ if (c >= META_END) *p++ = META_BIGVALUE; \
+ *p++ = c; \
+ okquantifier = TRUE; \
+ }
+#else
+#define PARSED_LITERAL(c, p) *p++ = c; okquantifier = TRUE;
+#endif
+
+/* Here's the actual function. */
+
+static int parse_regex(PCRE2_SPTR ptr, uint32_t options, BOOL *has_lookbehind,
+ compile_block *cb)
+{
+uint32_t c;
+uint32_t delimiter;
+uint32_t namelen;
+uint32_t class_range_state;
+uint32_t *verblengthptr = NULL; /* Value avoids compiler warning */
+uint32_t *previous_callout = NULL;
+uint32_t *parsed_pattern = cb->parsed_pattern;
+uint32_t *parsed_pattern_end = cb->parsed_pattern_end;
+uint32_t meta_quantifier = 0;
+uint16_t nest_depth = 0;
+int after_manual_callout = 0;
+int expect_cond_assert = 0;
+int errorcode = 0;
+int escape;
+int i;
+BOOL inescq = FALSE;
+BOOL inverbname = FALSE;
+BOOL utf = (options & PCRE2_UTF) != 0;
+BOOL isdupname;
+BOOL negate_class;
+BOOL okquantifier = FALSE;
+PCRE2_SPTR name;
+PCRE2_SPTR ptrend = cb->end_pattern;
+PCRE2_SPTR verbnamestart = NULL; /* Value avoids compiler warning */
+named_group *ng;
+nest_save *top_nest = NULL;
+nest_save *end_nests = (nest_save *)(cb->start_workspace + cb->workspace_size);
+
+/* The size of the nest_save structure might not be a factor of the size of the
+workspace. Therefore we must round down end_nests so as to correctly avoid
+creating a nest_save that spans the end of the workspace. */
+
+end_nests = (nest_save *)((char *)end_nests -
+ ((cb->workspace_size * sizeof(PCRE2_UCHAR)) % sizeof(nest_save)));
+
+/* Now scan the pattern */
+
+*has_lookbehind = FALSE;
+
+while (ptr < ptrend)
+ {
+ int prev_expect_cond_assert;
+ uint32_t min_repeat, max_repeat;
+ uint32_t set, unset, *optset;
+ uint32_t terminator;
+ uint32_t prev_meta_quantifier;
+ BOOL prev_okquantifier;
+ PCRE2_SPTR tempptr;
+ PCRE2_SPTR thisptr;
+ PCRE2_SIZE offset;
+
+ if (parsed_pattern >= parsed_pattern_end)
+ {
+ errorcode = ERR63; /* Internal error (parsed pattern overflow) */
+ goto FAILED;
+ }
+
+ if (nest_depth > cb->cx->parens_nest_limit)
+ {
+ errorcode = ERR19;
+ goto FAILED;
+ }
+
+ /* Get next input character, save its position for callout handling. */
+
+ thisptr = ptr;
+ GETCHARINCTEST(c, ptr);
+
+ /* Copy quoted literals until \E, allowing for the possibility of automatic
+ callouts, except when processing a (*VERB) "name". */
+
+ if (inescq)
+ {
+ if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)
+ {
+ inescq = FALSE;
+ ptr++; /* Skip E */
+ }
+ else
+ {
+ if (expect_cond_assert > 0) /* A literal is not allowed if we are */
+ { /* expecting a conditional assertion, */
+ ptr--; /* but an empty \Q\E sequence is OK. */
+ errorcode = ERR28;
+ goto FAILED;
+ }
+ if (!inverbname && after_manual_callout-- <= 0)
+ parsed_pattern = manage_callouts(thisptr, &previous_callout, options,
+ parsed_pattern, cb);
+ PARSED_LITERAL(c, parsed_pattern);
+ meta_quantifier = 0;
+ }
+ continue; /* Next character */
+ }
+
+ /* If we are processing the "name" part of a (*VERB:NAME) item, all
+ characters up to the closing parenthesis are literals except when
+ PCRE2_ALT_VERBNAMES is set. That causes backslash interpretation, but only \Q
+ and \E and escaped characters are allowed (no character types such as \d). If
+ PCRE2_EXTENDED is also set, we must ignore white space and # comments. Do
+ this by not entering the special (*VERB:NAME) processing - they are then
+ picked up below. Note that c is a character, not a code unit, so we must not
+ use MAX_255 to test its size because MAX_255 tests code units and is assumed
+ TRUE in 8-bit mode. */
+
+ if (inverbname &&
+ (
+ /* EITHER: not both options set */
+ ((options & (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) !=
+ (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) ||
+ /* OR: character > 255 */
+ c > 255 ||
+ /* OR: not a # comment or white space */
+ (c != CHAR_NUMBER_SIGN && (cb->ctypes[c] & ctype_space) == 0)
+ ))
+ {
+ PCRE2_SIZE verbnamelength;
+
+ switch(c)
+ {
+ default:
+ PARSED_LITERAL(c, parsed_pattern);
+ break;
+
+ case CHAR_RIGHT_PARENTHESIS:
+ inverbname = FALSE;
+ okquantifier = FALSE; /* Was probably set by literals */
+ /* This is the length in characters */
+ verbnamelength = (PCRE2_SIZE)(parsed_pattern - verblengthptr - 1);
+ /* But the limit on the length is in code units */
+ if (ptr - verbnamestart - 1 > (int)MAX_MARK)
+ {
+ ptr--;
+ errorcode = ERR76;
+ goto FAILED;
+ }
+ *verblengthptr = (uint32_t)verbnamelength;
+ break;
+
+ case CHAR_BACKSLASH:
+ if ((options & PCRE2_ALT_VERBNAMES) != 0)
+ {
+ escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,
+ FALSE, cb);
+ if (errorcode != 0) goto FAILED;
+ }
+ else escape = 0; /* Treat all as literal */
+
+ switch(escape)
+ {
+ case 0:
+ PARSED_LITERAL(c, parsed_pattern);
+ break;
+
+ case ESC_Q:
+ inescq = TRUE;
+ break;
+
+ case ESC_E: /* Ignore */
+ break;
+
+ default:
+ errorcode = ERR40; /* Invalid in verb name */
+ goto FAILED;
+ }
+ }
+ continue; /* Next character in pattern */
+ }
+
+ /* Not a verb name character. At this point we must process everything that
+ must not change the quantification state. This is mainly comments, but we
+ handle \Q and \E here as well, so that an item such as A\Q\E+ is treated as
+ A+, as in Perl. An isolated \E is ignored. */
+
+ if (c == CHAR_BACKSLASH && ptr < ptrend)
+ {
+ if (*ptr == CHAR_Q || *ptr == CHAR_E)
+ {
+ inescq = *ptr == CHAR_Q;
+ ptr++;
+ continue;
+ }
+ }
+
+ /* Skip over whitespace and # comments in extended mode. Note that c is a
+ character, not a code unit, so we must not use MAX_255 to test its size
+ because MAX_255 tests code units and is assumed TRUE in 8-bit mode. */
+
+ if ((options & PCRE2_EXTENDED) != 0)
+ {
+ if (c < 256 && (cb->ctypes[c] & ctype_space) != 0) continue;
+ if (c == CHAR_NUMBER_SIGN)
+ {
+ while (ptr < ptrend)
+ {
+ if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */
+ { /* IS_NEWLINE sets cb->nllen. */
+ ptr += cb->nllen;
+ break;
+ }
+ ptr++;
+#ifdef SUPPORT_UNICODE
+ if (utf) FORWARDCHARTEST(ptr, ptrend);
+#endif
+ }
+ continue; /* Next character in pattern */
+ }
+ }
+
+ /* Skip over bracketed comments */
+
+ if (c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 2 &&
+ ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN)
+ {
+ while (++ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS);
+ if (ptr >= ptrend)
+ {
+ errorcode = ERR18; /* A special error for missing ) in a comment */
+ goto FAILED; /* to make it easier to debug. */
+ }
+ ptr++;
+ continue; /* Next character in pattern */
+ }
+
+ /* If the next item is not a quantifier, fill in length of any previous
+ callout and create an auto callout if required. */
+
+ if (c != CHAR_ASTERISK && c != CHAR_PLUS && c != CHAR_QUESTION_MARK &&
+ (c != CHAR_LEFT_CURLY_BRACKET ||
+ (tempptr = ptr,
+ !read_repeat_counts(&tempptr, ptrend, NULL, NULL, &errorcode))))
+ {
+ if (after_manual_callout-- <= 0)
+ parsed_pattern = manage_callouts(thisptr, &previous_callout, options,
+ parsed_pattern, cb);
+ }
+
+ /* If expect_cond_assert is 2, we have just passed (?( and are expecting an
+ assertion, possibly preceded by a callout. If the value is 1, we have just
+ had the callout and expect an assertion. There must be at least 3 more
+ characters in all cases. When expect_cond_assert is 2, we know that the
+ current character is an opening parenthesis, as otherwise we wouldn't be
+ here. However, when it is 1, we need to check, and it's easiest just to check
+ always. Note that expect_cond_assert may be negative, since all callouts just
+ decrement it. */
+
+ if (expect_cond_assert > 0)
+ {
+ BOOL ok = c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 3 &&
+ ptr[0] == CHAR_QUESTION_MARK;
+ if (ok) switch(ptr[1])
+ {
+ case CHAR_C:
+ ok = expect_cond_assert == 2;
+ break;
+
+ case CHAR_EQUALS_SIGN:
+ case CHAR_EXCLAMATION_MARK:
+ break;
+
+ case CHAR_LESS_THAN_SIGN:
+ ok = ptr[2] == CHAR_EQUALS_SIGN || ptr[2] == CHAR_EXCLAMATION_MARK;
+ break;
+
+ default:
+ ok = FALSE;
+ }
+
+ if (!ok)
+ {
+ ptr--; /* Adjust error offset */
+ errorcode = ERR28;
+ goto FAILED;
+ }
+ }
+
+ /* Remember whether we are expecting a conditional assertion, and set the
+ default for this item. */
+
+ prev_expect_cond_assert = expect_cond_assert;
+ expect_cond_assert = 0;
+
+ /* Remember quantification status for the previous significant item, then set
+ default for this item. */
+
+ prev_okquantifier = okquantifier;
+ prev_meta_quantifier = meta_quantifier;
+ okquantifier = FALSE;
+ meta_quantifier = 0;
+
+ /* If the previous significant item was a quantifier, adjust the parsed code
+ if there is a following modifier. The base meta value is always followed by
+ the PLUS and QUERY values, in that order. We do this here rather than after
+ reading a quantifier so that intervening comments and /x whitespace can be
+ ignored without having to replicate code. */
+
+ if (prev_meta_quantifier != 0 && (c == CHAR_QUESTION_MARK || c == CHAR_PLUS))
+ {
+ parsed_pattern[(prev_meta_quantifier == META_MINMAX)? -3 : -1] =
+ prev_meta_quantifier + ((c == CHAR_QUESTION_MARK)?
+ 0x00020000u : 0x00010000u);
+ continue; /* Next character in pattern */
+ }
+
+
+ /* Process the next item in the main part of a pattern. */
+
+ switch(c)
+ {
+ default: /* Non-special character */
+ PARSED_LITERAL(c, parsed_pattern);
+ break;
+
+
+ /* ---- Escape sequence ---- */
+
+ case CHAR_BACKSLASH:
+ escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,
+ FALSE, cb);
+ if (errorcode != 0) goto FAILED;
+
+ /* The escape was a data character. */
+
+ if (escape == 0)
+ {
+ PARSED_LITERAL(c, parsed_pattern);
+ }
+
+ /* The escape was a back (or forward) reference. We keep the offset in
+ order to give a more useful diagnostic for a bad forward reference. For
+ references to groups numbered less than 10 we can't use more than two items
+ in parsed_pattern because they may be just two characters in the input (and
+ in a 64-bit world an offset may need two elements). So for them, the offset
+ of the first occurrent is held in a special vector. */
+
+ else if (escape < 0)
+ {
+ offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 1);
+ escape = -escape;
+ *parsed_pattern++ = META_BACKREF | (uint32_t)escape;
+ if (escape < 10)
+ {
+ if (cb->small_ref_offset[escape] == PCRE2_UNSET)
+ cb->small_ref_offset[escape] = offset;
+ }
+ else
+ {
+ PUTOFFSET(offset, parsed_pattern);
+ }
+ okquantifier = TRUE;
+ }
+
+ /* The escape was a character class such as \d etc. or other special
+ escape indicator such as \A or \X. Most of them generate just a single
+ parsed item, but \P and \p are followed by a 16-bit type and a 16-bit
+ value. They are supported only when Unicode is available. The type and
+ value are packed into a single 32-bit value so that the whole sequences
+ uses only two elements in the parsed_vector. This is because the same
+ coding is used if \d (for example) is turned into \p{Nd} when PCRE2_UCP is
+ set.
+
+ There are also some cases where the escape sequence is followed by a name:
+ \k{name}, \k<name>, and \k'name' are backreferences by name, and \g<name>
+ and \g'name' are subroutine calls by name; \g{name} is a synonym for
+ \k{name}. Note that \g<number> and \g'number' are handled by check_escape()
+ and returned as a negative value (handled above). A name is coded as an
+ offset into the pattern and a length. */
+
+ else switch (escape)
+ {
+ case ESC_C:
+#ifdef NEVER_BACKSLASH_C
+ errorcode = ERR85;
+ goto FAILED;
+#else
+ if ((options & PCRE2_NEVER_BACKSLASH_C) != 0)
+ {
+ errorcode = ERR83;
+ goto FAILED;
+ }
+#endif
+ okquantifier = TRUE;
+ *parsed_pattern++ = META_ESCAPE + escape;
+ break;
+
+ case ESC_X:
+#ifndef SUPPORT_UNICODE
+ errorcode = ERR45; /* Supported only with Unicode support */
+ goto FAILED;
+#endif
+ case ESC_H:
+ case ESC_h:
+ case ESC_N:
+ case ESC_R:
+ case ESC_V:
+ case ESC_v:
+ okquantifier = TRUE;
+ *parsed_pattern++ = META_ESCAPE + escape;
+ break;
+
+ default: /* \A, \B, \b, \G, \K, \Z, \z cannot be quantified. */
+ *parsed_pattern++ = META_ESCAPE + escape;
+ break;
+
+ /* Escapes that change in UCP mode. Note that PCRE2_UCP will never be set
+ without Unicode support because it is checked when pcre2_compile() is
+ called. */
+
+ case ESC_d:
+ case ESC_D:
+ case ESC_s:
+ case ESC_S:
+ case ESC_w:
+ case ESC_W:
+ okquantifier = TRUE;
+ if ((options & PCRE2_UCP) == 0)
+ {
+ *parsed_pattern++ = META_ESCAPE + escape;
+ }
+ else
+ {
+ *parsed_pattern++ = META_ESCAPE +
+ ((escape == ESC_d || escape == ESC_s || escape == ESC_w)?
+ ESC_p : ESC_P);
+ switch(escape)
+ {
+ case ESC_d:
+ case ESC_D:
+ *parsed_pattern++ = (PT_PC << 16) | ucp_Nd;
+ break;
+
+ case ESC_s:
+ case ESC_S:
+ *parsed_pattern++ = PT_SPACE << 16;
+ break;
+
+ case ESC_w:
+ case ESC_W:
+ *parsed_pattern++ = PT_WORD << 16;
+ break;
+ }
+ }
+ break;
+
+ /* Unicode property matching */
+
+ case ESC_P:
+ case ESC_p:
+#ifdef SUPPORT_UNICODE
+ {
+ BOOL negated;
+ uint16_t ptype = 0, pdata = 0;
+ if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
+ goto FAILED;
+ if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;
+ *parsed_pattern++ = META_ESCAPE + escape;
+ *parsed_pattern++ = (ptype << 16) | pdata;
+ okquantifier = TRUE;
+ }
+#else
+ errorcode = ERR45;
+ goto FAILED;
+#endif
+ break; /* End \P and \p */
+
+ /* When \g is used with quotes or angle brackets as delimiters, it is a
+ numerical or named subroutine call, and control comes here. When used
+ with brace delimiters it is a numberical back reference and does not come
+ here because check_escape() returns it directly as a reference. \k is
+ always a named back reference. */
+
+ case ESC_g:
+ case ESC_k:
+ if (ptr >= ptrend || (*ptr != CHAR_LEFT_CURLY_BRACKET &&
+ *ptr != CHAR_LESS_THAN_SIGN && *ptr != CHAR_APOSTROPHE))
+ {
+ errorcode = (escape == ESC_g)? ERR57 : ERR69;
+ goto FAILED;
+ }
+ terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
+ CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
+
+ /* For a non-braced \g, check for a numerical recursion. */
+
+ if (escape == ESC_g && terminator != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ PCRE2_SPTR p = ptr + 1;
+
+ if (read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,
+ &errorcode))
+ {
+ if (p >= ptrend || *p != terminator)
+ {
+ errorcode = ERR57;
+ goto FAILED;
+ }
+ ptr = p;
+ goto SET_RECURSION;
+ }
+ if (errorcode != 0) goto FAILED;
+ }
+
+ /* Not a numerical recursion */
+
+ if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen,
+ &errorcode, cb)) goto FAILED;
+
+ /* \k and \g when used with braces are back references, whereas \g used
+ with quotes or angle brackets is a recursion */
+
+ *parsed_pattern++ =
+ (escape == ESC_k || terminator == CHAR_RIGHT_CURLY_BRACKET)?
+ META_BACKREF_BYNAME : META_RECURSE_BYNAME;
+ *parsed_pattern++ = namelen;
+
+ PUTOFFSET(offset, parsed_pattern);
+ okquantifier = TRUE;
+ break;
+ }
+ break; /* End escape sequence processing */
+
+
+ /* ---- Single-character special items ---- */
+
+ case CHAR_CIRCUMFLEX_ACCENT:
+ *parsed_pattern++ = META_CIRCUMFLEX;
+ break;
+
+ case CHAR_DOLLAR_SIGN:
+ *parsed_pattern++ = META_DOLLAR;
+ break;
+
+ case CHAR_DOT:
+ *parsed_pattern++ = META_DOT;
+ okquantifier = TRUE;
+ break;
+
+
+ /* ---- Single-character quantifiers ---- */
+
+ case CHAR_ASTERISK:
+ meta_quantifier = META_ASTERISK;
+ goto CHECK_QUANTIFIER;
+
+ case CHAR_PLUS:
+ meta_quantifier = META_PLUS;
+ goto CHECK_QUANTIFIER;
+
+ case CHAR_QUESTION_MARK:
+ meta_quantifier = META_QUERY;
+ goto CHECK_QUANTIFIER;
+
+
+ /* ---- Potential {n,m} quantifier ---- */
+
+ case CHAR_LEFT_CURLY_BRACKET:
+ if (!read_repeat_counts(&ptr, ptrend, &min_repeat, &max_repeat,
+ &errorcode))
+ {
+ if (errorcode != 0) goto FAILED; /* Error in quantifier. */
+ PARSED_LITERAL(c, parsed_pattern); /* Not a quantifier */
+ break; /* No more quantifier processing */
+ }
+ meta_quantifier = META_MINMAX;
+ /* Fall through */
+
+
+ /* ---- Quantifier post-processing ---- */
+
+ /* Check that a quantifier is allowed after the previous item. */
+
+ CHECK_QUANTIFIER:
+ if (!prev_okquantifier)
+ {
+ errorcode = ERR9;
+ goto FAILED_BACK;
+ }
+
+ /* Now we can put the quantifier into the parsed pattern vector. At this
+ stage, we have only the basic quantifier. The check for a following + or ?
+ modifier happens at the top of the loop, after any intervening comments
+ have been removed. */
+
+ *parsed_pattern++ = meta_quantifier;
+ if (c == CHAR_LEFT_CURLY_BRACKET)
+ {
+ *parsed_pattern++ = min_repeat;
+ *parsed_pattern++ = max_repeat;
+ }
+ break;
+
+
+ /* ---- Character class ---- */
+
+ case CHAR_LEFT_SQUARE_BRACKET:
+ okquantifier = TRUE;
+
+ /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
+ used for "start of word" and "end of word". As these are otherwise illegal
+ sequences, we don't break anything by recognizing them. They are replaced
+ by \b(?=\w) and \b(?<=\w) respectively. Sequences like [a[:<:]] are
+ erroneous and are handled by the normal code below. */
+
+ if (ptrend - ptr >= 6 &&
+ (PRIV(strncmp_c8)(ptr, STRING_WEIRD_STARTWORD, 6) == 0 ||
+ PRIV(strncmp_c8)(ptr, STRING_WEIRD_ENDWORD, 6) == 0))
+ {
+ *parsed_pattern++ = META_ESCAPE + ESC_b;
+
+ if (ptr[2] == CHAR_LESS_THAN_SIGN)
+ {
+ *parsed_pattern++ = META_LOOKAHEAD;
+ }
+ else
+ {
+ *parsed_pattern++ = META_LOOKBEHIND;
+ *has_lookbehind = TRUE;
+
+ /* The offset is used only for the "non-fixed length" error; this won't
+ occur here, so just store zero. */
+
+ PUTOFFSET((PCRE2_SIZE)0, parsed_pattern);
+ }
+
+ if ((options & PCRE2_UCP) == 0)
+ *parsed_pattern++ = META_ESCAPE + ESC_w;
+ else
+ {
+ *parsed_pattern++ = META_ESCAPE + ESC_p;
+ *parsed_pattern++ = PT_WORD << 16;
+ }
+ *parsed_pattern++ = META_KET;
+ ptr += 6;
+ break;
+ }
+
+ /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
+ they are encountered at the top level, so we'll do that too. */
+
+ if (ptr < ptrend && (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||
+ *ptr == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, ptrend, &tempptr))
+ {
+ errorcode = (*ptr-- == CHAR_COLON)? ERR12 : ERR13;
+ goto FAILED;
+ }
+
+ /* Process a regular character class. If the first character is '^', set
+ the negation flag. If the first few characters (either before or after ^)
+ are \Q\E or \E we skip them too. This makes for compatibility with Perl. */
+
+ negate_class = FALSE;
+ while (ptr < ptrend)
+ {
+ GETCHARINCTEST(c, ptr);
+ if (c == CHAR_BACKSLASH)
+ {
+ if (ptr < ptrend && *ptr == CHAR_E) ptr++;
+ else if (ptrend - ptr >= 3 &&
+ PRIV(strncmp_c8)(ptr, STR_Q STR_BACKSLASH STR_E, 3) == 0)
+ ptr += 3;
+ else
+ break;
+ }
+ else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
+ negate_class = TRUE;
+ else break;
+ }
+
+ /* Now the real contents of the class; c has the first "real" character.
+ Empty classes are permitted only if the option is set. */
+
+ if (c == CHAR_RIGHT_SQUARE_BRACKET &&
+ (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0)
+ {
+ *parsed_pattern++ = negate_class? META_CLASS_EMPTY_NOT : META_CLASS_EMPTY;
+ break; /* End of class processing */
+ }
+
+ /* Process a non-empty class. */
+
+ *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS;
+ class_range_state = RANGE_NO;
+
+ /* In an EBCDIC environment, Perl treats alphabetic ranges specially
+ because there are holes in the encoding, and simply using the range A-Z
+ (for example) would include the characters in the holes. This applies only
+ to ranges where both values are literal; [\xC1-\xE9] is different to [A-Z]
+ in this respect. In order to accommodate this, we keep track of whether
+ character values are literal or not, and a state variable for handling
+ ranges. */
+
+ /* Loop for the contents of the class */
+
+ for (;;)
+ {
+ BOOL char_is_literal = TRUE;
+
+ /* Inside \Q...\E everything is literal except \E */
+
+ if (inescq)
+ {
+ if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)
+ {
+ inescq = FALSE; /* Reset literal state */
+ ptr++; /* Skip the 'E' */
+ goto CLASS_CONTINUE;
+ }
+ goto CLASS_LITERAL;
+ }
+
+ /* Handle POSIX class names. Perl allows a negation extension of the
+ form [:^name:]. A square bracket that doesn't match the syntax is
+ treated as a literal. We also recognize the POSIX constructions
+ [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
+ 5.6 and 5.8 do. */
+
+ if (c == CHAR_LEFT_SQUARE_BRACKET &&
+ ptrend - ptr >= 3 &&
+ (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||
+ *ptr == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, ptrend, &tempptr))
+ {
+ BOOL posix_negate = FALSE;
+ int posix_class;
+
+ /* Perl treats a hyphen before a POSIX class as a literal, not the
+ start of a range. However, it gives a warning in its warning mode. PCRE
+ does not have a warning mode, so we give an error, because this is
+ likely an error on the user's part. */
+
+ if (class_range_state == RANGE_STARTED)
+ {
+ errorcode = ERR50;
+ goto FAILED;
+ }
+
+ if (*ptr != CHAR_COLON)
+ {
+ errorcode = ERR13;
+ goto FAILED_BACK;
+ }
+
+ if (*(++ptr) == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ posix_negate = TRUE;
+ ptr++;
+ }
+
+ posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
+ if (posix_class < 0)
+ {
+ errorcode = ERR30;
+ goto FAILED;
+ }
+ ptr = tempptr + 2;
+
+ /* Perl treats a hyphen after a POSIX class as a literal, not the
+ start of a range. However, it gives a warning in its warning mode. PCRE
+ does not have a warning mode, so we give an error, because this is
+ likely an error on the user's part. */
+
+ if (ptr < ptrend && *ptr == CHAR_MINUS)
+ {
+ errorcode = ERR50;
+ goto FAILED;
+ }
+
+ /* Set "a hyphen is not the start of a range" just in case the POSIX
+ class is followed by \E or \Q\E (possibly repeated - fuzzers do that
+ kind of thing) and *then* a hyphen. This causes that hyphen to be
+ treated as a literal. I don't think it's worth setting up special
+ apparatus to do otherwise. */
+
+ class_range_state = RANGE_NO;
+
+ /* When PCRE2_UCP is set, some of the POSIX classes are converted to
+ use Unicode properties \p or \P or, in one case, \h or \H. The
+ substitutes table has two values per class, containing the type and
+ value of a \p or \P item. The special cases are specified with a
+ negative type: a non-zero value causes \h or \H to be used, and a zero
+ value falls through to behave like a non-UCP POSIX class. */
+
+#ifdef SUPPORT_UNICODE
+ if ((options & PCRE2_UCP) != 0)
+ {
+ int ptype = posix_substitutes[2*posix_class];
+ int pvalue = posix_substitutes[2*posix_class + 1];
+ if (ptype >= 0)
+ {
+ *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_P : ESC_p);
+ *parsed_pattern++ = (ptype << 16) | pvalue;
+ goto CLASS_CONTINUE;
+ }
+
+ if (pvalue != 0)
+ {
+ *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_H : ESC_h);
+ goto CLASS_CONTINUE;
+ }
+
+ /* Fall through */
+ }
+#endif /* SUPPORT_UNICODE */
+
+ /* Non-UCP POSIX class */
+
+ *parsed_pattern++ = posix_negate? META_POSIX_NEG : META_POSIX;
+ *parsed_pattern++ = posix_class;
+ }
+
+ /* Handle potential start of range */
+
+ else if (c == CHAR_MINUS && class_range_state >= RANGE_OK_ESCAPED)
+ {
+ *parsed_pattern++ = (class_range_state == RANGE_OK_LITERAL)?
+ META_RANGE_LITERAL : META_RANGE_ESCAPED;
+ class_range_state = RANGE_STARTED;
+ }
+
+ /* Handle a literal character */
+
+ else if (c != CHAR_BACKSLASH)
+ {
+ CLASS_LITERAL:
+ if (class_range_state == RANGE_STARTED)
+ {
+ if (c == parsed_pattern[-2]) /* Optimize one-char range */
+ parsed_pattern--;
+ else if (parsed_pattern[-2] > c) /* Check range is in order */
+ {
+ errorcode = ERR8;
+ goto FAILED_BACK;
+ }
+ else
+ {
+ if (!char_is_literal && parsed_pattern[-1] == META_RANGE_LITERAL)
+ parsed_pattern[-1] = META_RANGE_ESCAPED;
+ PARSED_LITERAL(c, parsed_pattern);
+ }
+ class_range_state = RANGE_NO;
+ }
+ else /* Potential start of range */
+ {
+ class_range_state = char_is_literal?
+ RANGE_OK_LITERAL : RANGE_OK_ESCAPED;
+ PARSED_LITERAL(c, parsed_pattern);
+ }
+ }
+
+ /* Handle escapes in a class */
+
+ else
+ {
+ escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode,
+ options, TRUE, cb);
+
+ if (errorcode != 0) goto FAILED;
+ if (escape == 0) /* Escaped character code point is in c */
+ {
+ char_is_literal = FALSE;
+ goto CLASS_LITERAL;
+ }
+
+ /* These three escapes do not alter the class range state. */
+
+ if (escape == ESC_b)
+ {
+ c = CHAR_BS; /* \b is backspace in a class */
+ char_is_literal = FALSE;
+ goto CLASS_LITERAL;
+ }
+
+ else if (escape == ESC_Q)
+ {
+ inescq = TRUE; /* Enter literal mode */
+ goto CLASS_CONTINUE;
+ }
+
+ else if (escape == ESC_E) /* Ignore orphan \E */
+ goto CLASS_CONTINUE;
+
+ /* The second part of a range can be a single-character escape
+ sequence (detected above), but not any of the other escapes. Perl
+ treats a hyphen as a literal in such circumstances. However, in Perl's
+ warning mode, a warning is given, so PCRE now faults it, as it is
+ almost certainly a mistake on the user's part. */
+
+ if (class_range_state == RANGE_STARTED)
+ {
+ errorcode = ERR50;
+ goto FAILED;
+ }
+
+ /* Of the remaining escapes, only those that define characters are
+ allowed in a class. None may start a range. */
+
+ class_range_state = RANGE_NO;
+ switch(escape)
+ {
+ case ESC_N:
+ errorcode = ERR71; /* Not supported in a class */
+ goto FAILED;
+
+ case ESC_H:
+ case ESC_h:
+ case ESC_V:
+ case ESC_v:
+ *parsed_pattern++ = META_ESCAPE + escape;
+ break;
+
+ /* These escapes are converted to Unicode property tests when
+ PCRE2_UCP is set. */
+
+ case ESC_d:
+ case ESC_D:
+ case ESC_s:
+ case ESC_S:
+ case ESC_w:
+ case ESC_W:
+ if ((options & PCRE2_UCP) == 0)
+ {
+ *parsed_pattern++ = META_ESCAPE + escape;
+ }
+ else
+ {
+ *parsed_pattern++ = META_ESCAPE +
+ ((escape == ESC_d || escape == ESC_s || escape == ESC_w)?
+ ESC_p : ESC_P);
+ switch(escape)
+ {
+ case ESC_d:
+ case ESC_D:
+ *parsed_pattern++ = (PT_PC << 16) | ucp_Nd;
+ break;
+
+ case ESC_s:
+ case ESC_S:
+ *parsed_pattern++ = PT_SPACE << 16;
+ break;
+
+ case ESC_w:
+ case ESC_W:
+ *parsed_pattern++ = PT_WORD << 16;
+ break;
+ }
+ }
+ break;
+
+ /* Explicit Unicode property matching */
+
+ case ESC_P:
+ case ESC_p:
+#ifdef SUPPORT_UNICODE
+ {
+ BOOL negated;
+ uint16_t ptype = 0, pdata = 0;
+ if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
+ goto FAILED;
+ if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;
+ *parsed_pattern++ = META_ESCAPE + escape;
+ *parsed_pattern++ = (ptype << 16) | pdata;
+ }
+#else
+ errorcode = ERR45;
+ goto FAILED;
+#endif
+ break; /* End \P and \p */
+
+ default: /* All others are not allowed in a class */
+ errorcode = ERR7;
+ goto FAILED_BACK;
+ }
+ }
+
+ /* Proceed to next thing in the class. */
+
+ CLASS_CONTINUE:
+ if (ptr >= ptrend)
+ {
+ errorcode = ERR6; /* Missing terminating ']' */
+ goto FAILED;
+ }
+ GETCHARINCTEST(c, ptr);
+ if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break;
+ } /* End of class-processing loop */
+
+ if (class_range_state == RANGE_STARTED)
+ {
+ parsed_pattern[-1] = CHAR_MINUS;
+ class_range_state = RANGE_NO;
+ }
+
+ *parsed_pattern++ = META_CLASS_END;
+ break; /* End of character class */
+
+
+ /* ---- Opening parenthesis ---- */
+
+ case CHAR_LEFT_PARENTHESIS:
+ if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+ /* If ( is not followed by ? it is either a capture or a special verb. */
+
+ if (*ptr != CHAR_QUESTION_MARK)
+ {
+ const char *vn;
+
+ /* Handle capturing brackets (or non-capturing if auto-capture is turned
+ off). */
+
+ if (*ptr != CHAR_ASTERISK)
+ {
+ nest_depth++;
+ if ((options & PCRE2_NO_AUTO_CAPTURE) == 0)
+ {
+ cb->bracount++;
+ *parsed_pattern++ = META_CAPTURE | cb->bracount;
+ }
+ else *parsed_pattern++ = META_NOCAPTURE;
+ }
+
+
+ /* ---- Handle (*VERB) and (*VERB:NAME) ---- */
+
+ /* Do nothing for (*) so it gives a "bad quantifier" error rather than
+ "(*MARK) must have an argument". */
+
+ else if (ptrend - ptr > 1 && ptr[1] != CHAR_RIGHT_PARENTHESIS)
+ {
+ vn = verbnames;
+ if (!read_name(&ptr, ptrend, 0, &offset, &name, &namelen, &errorcode,
+ cb)) goto FAILED;
+ if (ptr >= ptrend || (*ptr != CHAR_COLON &&
+ *ptr != CHAR_RIGHT_PARENTHESIS))
+ {
+ errorcode = ERR60; /* Malformed */
+ goto FAILED;
+ }
+
+ /* Scan the table of verb names */
+
+ for (i = 0; i < verbcount; i++)
+ {
+ if (namelen == verbs[i].len &&
+ PRIV(strncmp_c8)(name, vn, namelen) == 0)
+ break;
+ vn += verbs[i].len + 1;
+ }
+
+ if (i >= verbcount)
+ {
+ errorcode = ERR60; /* Verb not recognized */
+ goto FAILED;
+ }
+
+ /* An empty argument is treated as no argument. */
+
+ if (*ptr == CHAR_COLON && ptr + 1 < ptrend &&
+ ptr[1] == CHAR_RIGHT_PARENTHESIS)
+ ptr++; /* Advance to the closing parens */
+
+ /* Check for mandatory non-empty argument; this is (*MARK) */
+
+ if (verbs[i].has_arg > 0 && *ptr != CHAR_COLON)
+ {
+ errorcode = ERR66;
+ goto FAILED;
+ }
+
+ /* It appears that Perl allows any characters whatsoever, other than a
+ closing parenthesis, to appear in arguments ("names"), so we no longer
+ insist on letters, digits, and underscores. Perl does not, however, do
+ any interpretation within arguments, and has no means of including a
+ closing parenthesis. PCRE supports escape processing but only when it
+ is requested by an option. We set inverbname TRUE here, and let the
+ main loop take care of this so that escape and \x processing is done by
+ the main code above. */
+
+ if (*ptr++ == CHAR_COLON) /* Skip past : or ) */
+ {
+ if (verbs[i].has_arg < 0) /* Argument is forbidden */
+ {
+ errorcode = ERR59;
+ goto FAILED;
+ }
+ *parsed_pattern++ = verbs[i].meta +
+ ((verbs[i].meta != META_MARK)? 0x00010000u:0);
+ verblengthptr = parsed_pattern++;
+ verbnamestart = ptr;
+ inverbname = TRUE;
+ }
+ else /* No verb "name" argument */
+ {
+ *parsed_pattern++ = verbs[i].meta;
+ }
+ } /* End of (*VERB) handling */
+ break; /* Done with this parenthesis */
+ } /* End of groups that don't start with (? */
+
+
+ /* ---- Items starting (? ---- */
+
+ /* The type of item is determined by what follows (?. Handle (?| and option
+ changes under "default" because both need a new block on the nest stack.
+ Comments starting with (?# are handled above. Note that there is some
+ ambiguity about the sequence (?- because if a digit follows it's a relative
+ recursion or subroutine call whereas otherwise it's an option unsetting. */
+
+ if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+ switch(*ptr)
+ {
+ default:
+ if (*ptr == CHAR_MINUS && ptrend - ptr > 1 && IS_DIGIT(ptr[1]))
+ goto RECURSION_BYNUMBER; /* The + case is handled by CHAR_PLUS */
+
+ /* We now have either (?| or a (possibly empty) option setting,
+ optionally followed by a non-capturing group. */
+
+ nest_depth++;
+ if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
+ else if (++top_nest >= end_nests)
+ {
+ errorcode = ERR84;
+ goto FAILED;
+ }
+ top_nest->nest_depth = nest_depth;
+ top_nest->flags = 0;
+ if ((options & PCRE2_EXTENDED) != 0) top_nest->flags |= NSF_EXTENDED;
+ if ((options & PCRE2_DUPNAMES) != 0) top_nest->flags |= NSF_DUPNAMES;
+
+ /* Start of non-capturing group that resets the capture count for each
+ branch. */
+
+ if (*ptr == CHAR_VERTICAL_LINE)
+ {
+ top_nest->reset_group = (uint16_t)cb->bracount;
+ top_nest->max_group = (uint16_t)cb->bracount;
+ top_nest->flags |= NSF_RESET;
+ cb->external_flags |= PCRE2_DUPCAPUSED;
+ *parsed_pattern++ = META_NOCAPTURE;
+ ptr++;
+ }
+
+ /* Scan for options imsxJU. We need to keep track of (?x) and (?J) for
+ use while scanning. The other options are used during the compiling
+ phases. */
+
+ else
+ {
+ top_nest->reset_group = 0;
+ top_nest->max_group = 0;
+ set = unset = 0;
+ optset = &set;
+
+ while (ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS &&
+ *ptr != CHAR_COLON)
+ {
+ switch (*ptr++)
+ {
+ case CHAR_MINUS: optset = &unset; break;
+
+ case CHAR_J: /* Record that it changed in the external options */
+ *optset |= PCRE2_DUPNAMES;
+ cb->external_flags |= PCRE2_JCHANGED;
+ break;
+
+ case CHAR_i: *optset |= PCRE2_CASELESS; break;
+ case CHAR_m: *optset |= PCRE2_MULTILINE; break;
+ case CHAR_s: *optset |= PCRE2_DOTALL; break;
+ case CHAR_x: *optset |= PCRE2_EXTENDED; break;
+ case CHAR_U: *optset |= PCRE2_UNGREEDY; break;
+
+ default:
+ errorcode = ERR11;
+ ptr--; /* Correct the offset */
+ goto FAILED;
+ }
+ }
+ options = (options | set) & (~unset);
+
+ /* If the options ended with ')' this is not the start of a nested
+ group with option changes, so the options change at this level.
+ In this case, if the previous level set up a nest block, discard the
+ one we have just created. Otherwise adjust it for the previous level.
+ If the options ended with ':' we are starting a non-capturing group,
+ possibly with an options setting. */
+
+ if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+ if (*ptr++ == CHAR_RIGHT_PARENTHESIS)
+ {
+ nest_depth--; /* This is not a nested group after all. */
+ if (top_nest > (nest_save *)(cb->start_workspace) &&
+ (top_nest-1)->nest_depth == nest_depth) top_nest--;
+ else top_nest->nest_depth = nest_depth;
+ }
+ else *parsed_pattern++ = META_NOCAPTURE;
+
+ /* If nothing changed, no need to record. */
+
+ if (set != 0 || unset != 0)
+ {
+ *parsed_pattern++ = META_OPTIONS;
+ *parsed_pattern++ = options;
+ }
+ } /* End options processing */
+ break; /* End default case after (? */
+
+
+ /* ---- Python syntax support ---- */
+
+ case CHAR_P:
+ if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+ /* (?P<name> is the same as (?<name>, which defines a named group. */
+
+ if (*ptr == CHAR_LESS_THAN_SIGN)
+ {
+ terminator = CHAR_GREATER_THAN_SIGN;
+ goto DEFINE_NAME;
+ }
+
+ /* (?P>name) is the same as (?&name), which is a recursion or subroutine
+ call. */
+
+ if (*ptr == CHAR_GREATER_THAN_SIGN) goto RECURSE_BY_NAME;
+
+ /* (?P=name) is the same as \k<name>, a back reference by name. Anything
+ else after (?P is an error. */
+
+ if (*ptr != CHAR_EQUALS_SIGN)
+ {
+ errorcode = ERR41;
+ goto FAILED;
+ }
+ if (!read_name(&ptr, ptrend, CHAR_RIGHT_PARENTHESIS, &offset, &name,
+ &namelen, &errorcode, cb)) goto FAILED;
+ *parsed_pattern++ = META_BACKREF_BYNAME;
+ *parsed_pattern++ = namelen;
+ PUTOFFSET(offset, parsed_pattern);
+ okquantifier = TRUE;
+ break; /* End of (?P processing */
+
+
+ /* ---- Recursion/subroutine calls by number ---- */
+
+ case CHAR_R:
+ i = 0; /* (?R) == (?R0) */
+ ptr++;
+ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ errorcode = ERR58;
+ goto FAILED;
+ }
+ goto SET_RECURSION;
+
+ /* An item starting (?- followed by a digit comes here via the "default"
+ case because (?- followed by a non-digit is an options setting. */
+
+ case CHAR_PLUS:
+ if (ptrend - ptr < 2 || !IS_DIGIT(ptr[1]))
+ {
+ errorcode = ERR29; /* Missing number */
+ goto FAILED;
+ }
+ /* Fall through */
+
+ case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
+ case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+ RECURSION_BYNUMBER:
+ if (!read_number(&ptr, ptrend,
+ (IS_DIGIT(*ptr))? -1:(int)(cb->bracount), /* + and - are relative */
+ MAX_GROUP_NUMBER, ERR61,
+ &i, &errorcode)) goto FAILED;
+ if (i < 0) /* NB (?0) is permitted */
+ {
+ errorcode = ERR15; /* Unknown group */
+ goto FAILED_BACK;
+ }
+ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ goto UNCLOSED_PARENTHESIS;
+
+ SET_RECURSION:
+ *parsed_pattern++ = META_RECURSE | (uint32_t)i;
+ offset = (PCRE2_SIZE)(ptr - cb->start_pattern);
+ ptr++;
+ PUTOFFSET(offset, parsed_pattern);
+ okquantifier = TRUE;
+ break; /* End of recursive call by number handling */
+
+
+ /* ---- Recursion/subroutine calls by name ---- */
+
+ case CHAR_AMPERSAND:
+ RECURSE_BY_NAME:
+ if (!read_name(&ptr, ptrend, CHAR_RIGHT_PARENTHESIS, &offset, &name,
+ &namelen, &errorcode, cb)) goto FAILED;
+ *parsed_pattern++ = META_RECURSE_BYNAME;
+ *parsed_pattern++ = namelen;
+ PUTOFFSET(offset, parsed_pattern);
+ okquantifier = TRUE;
+ break;
+
+ /* ---- Callout with numerical or string argument ---- */
+
+ case CHAR_C:
+ if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+ /* If the previous item was a condition starting (?(? an assertion,
+ optionally preceded by a callout, is expected. This is checked later on,
+ during actual compilation. However we need to identify this kind of
+ assertion in this pass because it must not be qualified. The value of
+ expect_cond_assert is set to 2 after (?(? is processed. We decrement it
+ for a callout - still leaving a positive value that identifies the
+ assertion. Multiple callouts or any other items will make it zero or
+ less, which doesn't matter because they will cause an error later. */
+
+ expect_cond_assert = prev_expect_cond_assert - 1;
+
+ /* If previous_callout is not NULL, it means this follows a previous
+ callout. If it was a manual callout, do nothing; this means its "length
+ of next pattern item" field will remain zero. If it was an automatic
+ callout, abolish it. */
+
+ if (previous_callout != NULL && (options & PCRE2_AUTO_CALLOUT) != 0 &&
+ previous_callout == parsed_pattern - 4 &&
+ parsed_pattern[-1] == 255)
+ parsed_pattern = previous_callout;
+
+ /* Save for updating next pattern item length, and skip one item before
+ completing. */
+
+ previous_callout = parsed_pattern;
+ after_manual_callout = 1;
+
+ /* Handle a string argument; specific delimiter is required. */
+
+ if (*ptr != CHAR_RIGHT_PARENTHESIS && !IS_DIGIT(*ptr))
+ {
+ PCRE2_SIZE calloutlength;
+ PCRE2_SPTR startptr = ptr;
+
+ delimiter = 0;
+ for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
+ {
+ if (*ptr == PRIV(callout_start_delims)[i])
+ {
+ delimiter = PRIV(callout_end_delims)[i];
+ break;
+ }
+ }
+ if (delimiter == 0)
+ {
+ errorcode = ERR82;
+ goto FAILED;
+ }
+
+ *parsed_pattern = META_CALLOUT_STRING;
+ parsed_pattern += 3; /* Skip pattern info */
+
+ for (;;)
+ {
+ if (++ptr >= ptrend)
+ {
+ errorcode = ERR81;
+ ptr = startptr; /* To give a more useful message */
+ goto FAILED;
+ }
+ if (*ptr == delimiter && (++ptr >= ptrend || *ptr != delimiter))
+ break;
+ }
+
+ calloutlength = (PCRE2_SIZE)(ptr - startptr);
+ if (calloutlength > UINT32_MAX)
+ {
+ errorcode = ERR72;
+ goto FAILED;
+ }
+ *parsed_pattern++ = (uint32_t)calloutlength;
+ offset = (PCRE2_SIZE)(startptr - cb->start_pattern);
+ PUTOFFSET(offset, parsed_pattern);
+ }
+
+ /* Handle a callout with an optional numerical argument, which must be
+ less than or equal to 255. A missing argument gives 0. */
+
+ else
+ {
+ int n = 0;
+ *parsed_pattern = META_CALLOUT_NUMBER; /* Numerical callout */
+ parsed_pattern += 3; /* Skip pattern info */
+ while (ptr < ptrend && IS_DIGIT(*ptr))
+ {
+ n = n * 10 + *ptr++ - CHAR_0;
+ if (n > 255)
+ {
+ errorcode = ERR38;
+ goto FAILED;
+ }
+ }
+ *parsed_pattern++ = n;
+ }
+
+ /* Both formats must have a closing parenthesis */
+
+ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ errorcode = ERR39;
+ goto FAILED;
+ }
+ ptr++;
+
+ /* Remember the offset to the next item in the pattern, and set a default
+ length. This should get updated after the next item is read. */
+
+ previous_callout[1] = ptr - cb->start_pattern;
+ previous_callout[2] = 0;
+ break; /* End callout */
+
+
+ /* ---- Conditional group ---- */
+
+ /* A condition can be an assertion, a number (referring to a numbered
+ group's having been set), a name (referring to a named group), or 'R',
+ referring to overall recursion. R<digits> and R&name are also permitted
+ for recursion state tests. Numbers may be preceded by + or - to specify a
+ relative group number.
+
+ There are several syntaxes for testing a named group: (?(name)) is used
+ by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
+
+ There are two unfortunate ambiguities. 'R' can be the recursive thing or
+ the name 'R' (and similarly for 'R' followed by digits). 'DEFINE' can be
+ the Perl DEFINE feature or the Python named test. We look for a name
+ first; if not found, we try the other case.
+
+ For compatibility with auto-callouts, we allow a callout to be specified
+ before a condition that is an assertion. */
+
+ case CHAR_LEFT_PARENTHESIS:
+ if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+ nest_depth++;
+
+ /* If the next character is ? there must be an assertion next (optionally
+ preceded by a callout). We do not check this here, but instead we set
+ expect_cond_assert to 2. If this is still greater than zero (callouts
+ decrement it) when the next assertion is read, it will be marked as a
+ condition that must not be repeated. A value greater than zero also
+ causes checking that an assertion (possibly with callout) follows. */
+
+ if (*ptr == CHAR_QUESTION_MARK)
+ {
+ *parsed_pattern++ = META_COND_ASSERT;
+ ptr--; /* Pull pointer back to the opening parenthesis. */
+ expect_cond_assert = 2;
+ break; /* End of conditional */
+ }
+
+ /* Handle (?([+-]number)... */
+
+ if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,
+ &errorcode))
+ {
+ if (i <= 0)
+ {
+ errorcode = ERR15;
+ goto FAILED;
+ }
+ *parsed_pattern++ = META_COND_NUMBER;
+ offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
+ PUTOFFSET(offset, parsed_pattern);
+ *parsed_pattern++ = i;
+ }
+ else if (errorcode != 0) goto FAILED; /* Number too big */
+
+ /* No number found. Handle the special case (?(VERSION[>]=n.m)... */
+
+ else if (ptrend - ptr >= 10 &&
+ PRIV(strncmp_c8)(ptr, STRING_VERSION, 7) == 0 &&
+ ptr[7] != CHAR_RIGHT_PARENTHESIS)
+ {
+ uint32_t ge = 0;
+ int major = 0;
+ int minor = 0;
+
+ ptr += 7;
+ if (*ptr == CHAR_GREATER_THAN_SIGN)
+ {
+ ge = 1;
+ ptr++;
+ }
+
+ /* NOTE: cannot write IS_DIGIT(*(++ptr)) here because IS_DIGIT
+ references its argument twice. */
+
+ if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr)))
+ goto BAD_VERSION_CONDITION;
+
+ if (!read_number(&ptr, ptrend, -1, 1000, ERR79, &major, &errorcode))
+ goto FAILED;
+
+ if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
+ if (*ptr == CHAR_DOT)
+ {
+ if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION;
+ if (!read_number(&ptr, ptrend, -1, 99 , ERR79, &minor, &errorcode))
+ goto FAILED;
+ if (minor < 10) minor *= 10;
+ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ goto BAD_VERSION_CONDITION;
+ }
+
+ *parsed_pattern++ = META_COND_VERSION;
+ *parsed_pattern++ = ge;
+ *parsed_pattern++ = major;
+ *parsed_pattern++ = minor;
+ }
+
+ /* All the remaining cases now require us to read a name. We cannot at
+ this stage distinguish ambiguous cases such as (?(R12) which might be a
+ recursion test by number or a name, because the named groups have not yet
+ all been identified. Those cases are treated as names, but given a
+ different META code. */
+
+ else
+ {
+ BOOL was_r_ampersand = FALSE;
+
+ if (*ptr == CHAR_R && ptrend - ptr > 1 && ptr[1] == CHAR_AMPERSAND)
+ {
+ terminator = CHAR_RIGHT_PARENTHESIS;
+ was_r_ampersand = TRUE;
+ ptr++;
+ }
+ else if (*ptr == CHAR_LESS_THAN_SIGN)
+ terminator = CHAR_GREATER_THAN_SIGN;
+ else if (*ptr == CHAR_APOSTROPHE)
+ terminator = CHAR_APOSTROPHE;
+ else
+ {
+ terminator = CHAR_RIGHT_PARENTHESIS;
+ ptr--; /* Point to char before name */
+ }
+ if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen,
+ &errorcode, cb)) goto FAILED;
+
+ /* Handle (?(R&name) */
+
+ if (was_r_ampersand)
+ {
+ *parsed_pattern = META_COND_RNAME;
+ ptr--; /* Back to closing parens */
+ }
+
+ /* Handle (?(name). If the name is "DEFINE" we identify it with a
+ special code. Likewise if the name consists of R followed only by
+ digits. Otherwise, handle it like a quoted name. */
+
+ else if (terminator == CHAR_RIGHT_PARENTHESIS)
+ {
+ if (namelen == 6 && PRIV(strncmp_c8)(name, STRING_DEFINE, 6) == 0)
+ *parsed_pattern = META_COND_DEFINE;
+ else
+ {
+ for (i = 1; i < (int)namelen; i++)
+ if (!IS_DIGIT(name[i])) break;
+ *parsed_pattern = (*name == CHAR_R && i >= (int)namelen)?
+ META_COND_RNUMBER : META_COND_NAME;
+ }
+ ptr--; /* Back to closing parens */
+ }
+
+ /* Handle (?('name') or (?(<name>) */
+
+ else *parsed_pattern = META_COND_NAME;
+
+ /* All these cases except DEFINE end with the name length and offset;
+ DEFINE just has an offset (for the "too many branches" error). */
+
+ if (*parsed_pattern++ != META_COND_DEFINE) *parsed_pattern++ = namelen;
+ PUTOFFSET(offset, parsed_pattern);
+ } /* End cases that read a name */
+
+ /* Check the closing parenthesis of the condition */
+
+ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ errorcode = ERR24;
+ goto FAILED;
+ }
+ ptr++;
+ break; /* End of condition processing */
+
+
+ /* ---- Atomic group ---- */
+
+ case CHAR_GREATER_THAN_SIGN:
+ *parsed_pattern++ = META_ATOMIC;
+ nest_depth++;
+ ptr++;
+ break;
+
+
+ /* ---- Lookahead assertions ---- */
+
+ case CHAR_EQUALS_SIGN:
+ *parsed_pattern++ = META_LOOKAHEAD;
+ ptr++;
+ goto POST_ASSERTION;
+
+ case CHAR_EXCLAMATION_MARK:
+ *parsed_pattern++ = META_LOOKAHEADNOT;
+ ptr++;
+ goto POST_ASSERTION;
+
+
+ /* ---- Lookbehind assertions ---- */
+
+ /* (?< followed by = or ! is a lookbehind assertion. Otherwise (?< is the
+ start of the name of a capturing group. */
+
+ case CHAR_LESS_THAN_SIGN:
+ if (ptrend - ptr <= 1 ||
+ (ptr[1] != CHAR_EQUALS_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK))
+ {
+ terminator = CHAR_GREATER_THAN_SIGN;
+ goto DEFINE_NAME;
+ }
+ *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?
+ META_LOOKBEHIND : META_LOOKBEHINDNOT;
+ *has_lookbehind = TRUE;
+ offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
+ PUTOFFSET(offset, parsed_pattern);
+ ptr += 2;
+ /* Fall through */
+
+ /* If the previous item was a condition starting (?(? an assertion,
+ optionally preceded by a callout, is expected. This is checked later on,
+ during actual compilation. However we need to identify this kind of
+ assertion in this pass because it must not be qualified. The value of
+ expect_cond_assert is set to 2 after (?(? is processed. We decrement it
+ for a callout - still leaving a positive value that identifies the
+ assertion. Multiple callouts or any other items will make it zero or
+ less, which doesn't matter because they will cause an error later. */
+
+ POST_ASSERTION:
+ nest_depth++;
+ if (prev_expect_cond_assert > 0)
+ {
+ if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
+ else if (++top_nest >= end_nests)
+ {
+ errorcode = ERR84;
+ goto FAILED;
+ }
+ top_nest->nest_depth = nest_depth;
+ top_nest->flags = NSF_CONDASSERT;
+ if ((options & PCRE2_EXTENDED) != 0) top_nest->flags |= NSF_EXTENDED;
+ if ((options & PCRE2_DUPNAMES) != 0) top_nest->flags |= NSF_DUPNAMES;
+ }
+ break;
+
+
+ /* ---- Define a named group ---- */
+
+ /* A named group may be defined as (?'name') or (?<name>). In the latter
+ case we jump to DEFINE_NAME from the disambiguation of (?< above with the
+ terminator set to '>'. */
+
+ case CHAR_APOSTROPHE:
+ terminator = CHAR_APOSTROPHE; /* Terminator */
+
+ DEFINE_NAME:
+ if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen,
+ &errorcode, cb)) goto FAILED;
+
+ /* We have a name for this capturing group. It is also assigned a number,
+ which is its primary means of identification. */
+
+ cb->bracount++;
+ *parsed_pattern++ = META_CAPTURE | cb->bracount;
+ nest_depth++;
+
+ /* Check not too many names */
+
+ if (cb->names_found >= MAX_NAME_COUNT)
+ {
+ errorcode = ERR49;
+ goto FAILED;
+ }
+
+ /* Adjust the entry size to accommodate the longest name found. */
+
+ if (namelen + IMM2_SIZE + 1 > cb->name_entry_size)
+ cb->name_entry_size = (uint16_t)(namelen + IMM2_SIZE + 1);
+
+ /* Scan the list to check for duplicates. For duplicate names, if the
+ number is the same, break the loop, which causes the name to be
+ discarded; otherwise, if DUPNAMES is not set, give an error.
+ If it is set, allow the name with a different number, but continue
+ scanning in case this is a duplicate with the same number. For
+ non-duplicate names, give an error if the number is duplicated. */
+
+ isdupname = FALSE;
+ ng = cb->named_groups;
+ for (i = 0; i < cb->names_found; i++, ng++)
+ {
+ if (namelen == ng->length &&
+ PRIV(strncmp)(name, ng->name, (PCRE2_SIZE)namelen) == 0)
+ {
+ if (ng->number == cb->bracount) break;
+ if ((options & PCRE2_DUPNAMES) == 0)
+ {
+ errorcode = ERR43;
+ goto FAILED;
+ }
+ isdupname = ng->isdup = TRUE; /* Mark as a duplicate */
+ cb->dupnames = TRUE; /* Duplicate names exist */
+ }
+ else if (ng->number == cb->bracount)
+ {
+ errorcode = ERR65;
+ goto FAILED;
+ }
+ }
+
+ if (i < cb->names_found) break; /* Ignore duplicate with same number */
+
+ /* Increase the list size if necessary */
+
+ if (cb->names_found >= cb->named_group_list_size)
+ {
+ uint32_t newsize = cb->named_group_list_size * 2;
+ named_group *newspace =
+ cb->cx->memctl.malloc(newsize * sizeof(named_group),
+ cb->cx->memctl.memory_data);
+ if (newspace == NULL)
+ {
+ errorcode = ERR21;
+ goto FAILED;
+ }
+
+ memcpy(newspace, cb->named_groups,
+ cb->named_group_list_size * sizeof(named_group));
+ if (cb->named_group_list_size > NAMED_GROUP_LIST_SIZE)
+ cb->cx->memctl.free((void *)cb->named_groups,
+ cb->cx->memctl.memory_data);
+ cb->named_groups = newspace;
+ cb->named_group_list_size = newsize;
+ }
+
+ /* Add this name to the list */
+
+ cb->named_groups[cb->names_found].name = name;
+ cb->named_groups[cb->names_found].length = (uint16_t)namelen;
+ cb->named_groups[cb->names_found].number = cb->bracount;
+ cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname;
+ cb->names_found++;
+ break;
+ } /* End of (? switch */
+ break; /* End of ( handling */
+
+
+ /* ---- Branch terminators ---- */
+
+ /* Alternation: reset the capture count if we are in a (?| group. */
+
+ case CHAR_VERTICAL_LINE:
+ if (top_nest != NULL && top_nest->nest_depth == nest_depth &&
+ (top_nest->flags & NSF_RESET) != 0)
+ {
+ if (cb->bracount > top_nest->max_group)
+ top_nest->max_group = (uint16_t)cb->bracount;
+ cb->bracount = top_nest->reset_group;
+ }
+ *parsed_pattern++ = META_ALT;
+ break;
+
+ /* End of group; reset the capture count to the maximum if we are in a (?|
+ group and/or reset the extended and dupnames options. Disallow quantifier
+ for a condition that is an assertion. */
+
+ case CHAR_RIGHT_PARENTHESIS:
+ okquantifier = TRUE;
+ if (top_nest != NULL && top_nest->nest_depth == nest_depth)
+ {
+ if ((top_nest->flags & NSF_RESET) != 0 &&
+ top_nest->max_group > cb->bracount)
+ cb->bracount = top_nest->max_group;
+ if ((top_nest->flags & NSF_EXTENDED) != 0) options |= PCRE2_EXTENDED;
+ else options &= ~PCRE2_EXTENDED;
+ if ((top_nest->flags & NSF_DUPNAMES) != 0) options |= PCRE2_DUPNAMES;
+ else options &= ~PCRE2_DUPNAMES;
+ if ((top_nest->flags & NSF_CONDASSERT) != 0)
+ okquantifier = FALSE;
+ if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL;
+ else top_nest--;
+ }
+ if (nest_depth == 0) /* Unmatched closing parenthesis */
+ {
+ errorcode = ERR22;
+ goto FAILED_BACK;
+ }
+ nest_depth--;
+ *parsed_pattern++ = META_KET;
+ break;
+ } /* End of switch on pattern character */
+ } /* End of main character scan loop */
+
+/* End of pattern reached. Check for missing ) at the end of a verb name. */
+
+if (inverbname && ptr >= ptrend)
+ {
+ errorcode = ERR60;
+ goto FAILED;
+ }
+
+/* Manage callout for the final item */
+
+parsed_pattern = manage_callouts(ptr, &previous_callout, options,
+ parsed_pattern, cb);
+
+/* Terminate the parsed pattern, then return success if all groups are closed.
+Otherwise we have unclosed parentheses. */
+
+if (parsed_pattern >= parsed_pattern_end)
+ {
+ errorcode = ERR63; /* Internal error (parsed pattern overflow) */
+ goto FAILED;
+ }
+*parsed_pattern = META_END;
+if (nest_depth == 0) return 0;
+
+UNCLOSED_PARENTHESIS:
+errorcode = ERR14;
+
+/* Come here for all failures. */
+
+FAILED:
+cb->erroroffset = (PCRE2_SIZE)(ptr - cb->start_pattern);
+return errorcode;
+
+/* Some errors need to indicate the previous character. */
+
+FAILED_BACK:
+ptr--;
+goto FAILED;
+
+/* This failure happens several times. */
+
+BAD_VERSION_CONDITION:
+errorcode = ERR79;
+goto FAILED;
+}
+
+
+
+/*************************************************
+* Find first significant op code *
+*************************************************/
+
+/* This is called by several functions that scan a compiled expression looking
+for a fixed first character, or an anchoring op code etc. It skips over things
+that do not influence this. For some calls, it makes sense to skip negative
+forward and all backward assertions, and also the \b assertion; for others it
+does not.
+
+Arguments:
+ code pointer to the start of the group
+ skipassert TRUE if certain assertions are to be skipped
+
+Returns: pointer to the first significant opcode
+*/
+
+static const PCRE2_UCHAR*
+first_significant_code(PCRE2_SPTR code, BOOL skipassert)
+{
+for (;;)
+ {
+ switch ((int)*code)
+ {
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ if (!skipassert) return code;
+ do code += GET(code, 1); while (*code == OP_ALT);
+ code += PRIV(OP_lengths)[*code];
+ break;
+
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ if (!skipassert) return code;
+ /* Fall through */
+
+ case OP_CALLOUT:
+ case OP_CREF:
+ case OP_DNCREF:
+ case OP_RREF:
+ case OP_DNRREF:
+ case OP_FALSE:
+ case OP_TRUE:
+ code += PRIV(OP_lengths)[*code];
+ break;
+
+ case OP_CALLOUT_STR:
+ code += GET(code, 1 + 2*LINK_SIZE);
+ break;
+
+ default:
+ return code;
+ }
+ }
+/* Control never reaches here */
+}
+
+
+
+#ifdef SUPPORT_UNICODE
+/*************************************************
+* Get othercase range *
+*************************************************/
+
+/* This function is passed the start and end of a class range in UCP mode. It
+searches up the characters, looking for ranges of characters in the "other"
+case. Each call returns the next one, updating the start address. A character
+with multiple other cases is returned on its own with a special return value.
+
+Arguments:
+ cptr points to starting character value; updated
+ d end value
+ ocptr where to put start of othercase range
+ odptr where to put end of othercase range
+
+Yield: -1 when no more
+ 0 when a range is returned
+ >0 the CASESET offset for char with multiple other cases
+ in this case, ocptr contains the original
+*/
+
+static int
+get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr,
+ uint32_t *odptr)
+{
+uint32_t c, othercase, next;
+unsigned int co;
+
+/* Find the first character that has an other case. If it has multiple other
+cases, return its case offset value. */
+
+for (c = *cptr; c <= d; c++)
+ {
+ if ((co = UCD_CASESET(c)) != 0)
+ {
+ *ocptr = c++; /* Character that has the set */
+ *cptr = c; /* Rest of input range */
+ return (int)co;
+ }
+ if ((othercase = UCD_OTHERCASE(c)) != c) break;
+ }
+
+if (c > d) return -1; /* Reached end of range */
+
+/* Found a character that has a single other case. Search for the end of the
+range, which is either the end of the input range, or a character that has zero
+or more than one other cases. */
+
+*ocptr = othercase;
+next = othercase + 1;
+
+for (++c; c <= d; c++)
+ {
+ if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break;
+ next++;
+ }
+
+*odptr = next - 1; /* End of othercase range */
+*cptr = c; /* Rest of input range */
+return 0;
+}
+#endif /* SUPPORT_UNICODE */
+
+
+
+/*************************************************
+* Add a character or range to a class (internal) *
+*************************************************/
+
+/* This function packages up the logic of adding a character or range of
+characters to a class. The character values in the arguments will be within the
+valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is
+called only from within the "add to class" group of functions, some of which
+are recursive and mutually recursive. The external entry point is
+add_to_class().
+
+Arguments:
+ classbits the bit map for characters < 256
+ uchardptr points to the pointer for extra data
+ options the options word
+ cb compile data
+ start start of range character
+ end end of range character
+
+Returns: the number of < 256 characters added
+ the pointer to extra data is updated
+*/
+
+static unsigned int
+add_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
+ uint32_t options, compile_block *cb, uint32_t start, uint32_t end)
+{
+uint32_t c;
+uint32_t classbits_end = (end <= 0xff ? end : 0xff);
+unsigned int n8 = 0;
+
+/* If caseless matching is required, scan the range and process alternate
+cases. In Unicode, there are 8-bit characters that have alternate cases that
+are greater than 255 and vice-versa. Sometimes we can just extend the original
+range. */
+
+if ((options & PCRE2_CASELESS) != 0)
+ {
+#ifdef SUPPORT_UNICODE
+ if ((options & PCRE2_UTF) != 0)
+ {
+ int rc;
+ uint32_t oc, od;
+
+ options &= ~PCRE2_CASELESS; /* Remove for recursive calls */
+ c = start;
+
+ while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0)
+ {
+ /* Handle a single character that has more than one other case. */
+
+ if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, options, cb,
+ PRIV(ucd_caseless_sets) + rc, oc);
+
+ /* Do nothing if the other case range is within the original range. */
+
+ else if (oc >= cb->class_range_start && od <= cb->class_range_end) continue;
+
+ /* Extend the original range if there is overlap, noting that if oc < c, we
+ can't have od > end because a subrange is always shorter than the basic
+ range. Otherwise, use a recursive call to add the additional range. */
+
+ else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */
+ else if (od > end && oc <= end + 1)
+ {
+ end = od; /* Extend upwards */
+ if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff);
+ }
+ else n8 += add_to_class_internal(classbits, uchardptr, options, cb, oc, od);
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+
+ /* Not UTF mode */
+
+ for (c = start; c <= classbits_end; c++)
+ {
+ SETBIT(classbits, cb->fcc[c]);
+ n8++;
+ }
+ }
+
+/* Now handle the originally supplied range. Adjust the final value according
+to the bit length - this means that the same lists of (e.g.) horizontal spaces
+can be used in all cases. */
+
+if ((options & PCRE2_UTF) == 0 && end > MAX_NON_UTF_CHAR)
+ end = MAX_NON_UTF_CHAR;
+
+if (start > cb->class_range_start && end < cb->class_range_end) return n8;
+
+/* Use the bitmap for characters < 256. Otherwise use extra data.*/
+
+for (c = start; c <= classbits_end; c++)
+ {
+ /* Regardless of start, c will always be <= 255. */
+ SETBIT(classbits, c);
+ n8++;
+ }
+
+#ifdef SUPPORT_WIDE_CHARS
+if (start <= 0xff) start = 0xff + 1;
+
+if (end >= start)
+ {
+ PCRE2_UCHAR *uchardata = *uchardptr;
+
+#ifdef SUPPORT_UNICODE
+ if ((options & PCRE2_UTF) != 0)
+ {
+ if (start < end)
+ {
+ *uchardata++ = XCL_RANGE;
+ uchardata += PRIV(ord2utf)(start, uchardata);
+ uchardata += PRIV(ord2utf)(end, uchardata);
+ }
+ else if (start == end)
+ {
+ *uchardata++ = XCL_SINGLE;
+ uchardata += PRIV(ord2utf)(start, uchardata);
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+
+ /* Without UTF support, character values are constrained by the bit length,
+ and can only be > 256 for 16-bit and 32-bit libraries. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ {}
+#else
+ if (start < end)
+ {
+ *uchardata++ = XCL_RANGE;
+ *uchardata++ = start;
+ *uchardata++ = end;
+ }
+ else if (start == end)
+ {
+ *uchardata++ = XCL_SINGLE;
+ *uchardata++ = start;
+ }
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ *uchardptr = uchardata; /* Updata extra data pointer */
+ }
+#else /* SUPPORT_WIDE_CHARS */
+ (void)uchardptr; /* Avoid compiler warning */
+#endif /* SUPPORT_WIDE_CHARS */
+
+return n8; /* Number of 8-bit characters */
+}
+
+
+
+#ifdef SUPPORT_UNICODE
+/*************************************************
+* Add a list of characters to a class (internal) *
+*************************************************/
+
+/* This function is used for adding a list of case-equivalent characters to a
+class when in UTF mode. This function is called only from within
+add_to_class_internal(), with which it is mutually recursive.
+
+Arguments:
+ classbits the bit map for characters < 256
+ uchardptr points to the pointer for extra data
+ options the options word
+ cb contains pointers to tables etc.
+ p points to row of 32-bit values, terminated by NOTACHAR
+ except character to omit; this is used when adding lists of
+ case-equivalent characters to avoid including the one we
+ already know about
+
+Returns: the number of < 256 characters added
+ the pointer to extra data is updated
+*/
+
+static unsigned int
+add_list_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
+ uint32_t options, compile_block *cb, const uint32_t *p, unsigned int except)
+{
+unsigned int n8 = 0;
+while (p[0] < NOTACHAR)
+ {
+ unsigned int n = 0;
+ if (p[0] != except)
+ {
+ while(p[n+1] == p[0] + n + 1) n++;
+ n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]);
+ }
+ p += n + 1;
+ }
+return n8;
+}
+#endif
+
+
+
+/*************************************************
+* External entry point for add range to class *
+*************************************************/
+
+/* This function sets the overall range so that the internal functions can try
+to avoid duplication when handling case-independence.
+
+Arguments:
+ classbits the bit map for characters < 256
+ uchardptr points to the pointer for extra data
+ options the options word
+ cb compile data
+ start start of range character
+ end end of range character
+
+Returns: the number of < 256 characters added
+ the pointer to extra data is updated
+*/
+
+static unsigned int
+add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options,
+ compile_block *cb, uint32_t start, uint32_t end)
+{
+cb->class_range_start = start;
+cb->class_range_end = end;
+return add_to_class_internal(classbits, uchardptr, options, cb, start, end);
+}
+
+
+/*************************************************
+* External entry point for add list to class *
+*************************************************/
+
+/* This function is used for adding a list of horizontal or vertical whitespace
+characters to a class. The list must be in order so that ranges of characters
+can be detected and handled appropriately. This function sets the overall range
+so that the internal functions can try to avoid duplication when handling
+case-independence.
+
+Arguments:
+ classbits the bit map for characters < 256
+ uchardptr points to the pointer for extra data
+ options the options word
+ cb contains pointers to tables etc.
+ p points to row of 32-bit values, terminated by NOTACHAR
+ except character to omit; this is used when adding lists of
+ case-equivalent characters to avoid including the one we
+ already know about
+
+Returns: the number of < 256 characters added
+ the pointer to extra data is updated
+*/
+
+static unsigned int
+add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options,
+ compile_block *cb, const uint32_t *p, unsigned int except)
+{
+unsigned int n8 = 0;
+while (p[0] < NOTACHAR)
+ {
+ unsigned int n = 0;
+ if (p[0] != except)
+ {
+ while(p[n+1] == p[0] + n + 1) n++;
+ cb->class_range_start = p[0];
+ cb->class_range_end = p[n];
+ n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]);
+ }
+ p += n + 1;
+ }
+return n8;
+}
+
+
+
+/*************************************************
+* Add characters not in a list to a class *
+*************************************************/
+
+/* This function is used for adding the complement of a list of horizontal or
+vertical whitespace to a class. The list must be in order.
+
+Arguments:
+ classbits the bit map for characters < 256
+ uchardptr points to the pointer for extra data
+ options the options word
+ cb contains pointers to tables etc.
+ p points to row of 32-bit values, terminated by NOTACHAR
+
+Returns: the number of < 256 characters added
+ the pointer to extra data is updated
+*/
+
+static unsigned int
+add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
+ uint32_t options, compile_block *cb, const uint32_t *p)
+{
+BOOL utf = (options & PCRE2_UTF) != 0;
+unsigned int n8 = 0;
+if (p[0] > 0)
+ n8 += add_to_class(classbits, uchardptr, options, cb, 0, p[0] - 1);
+while (p[0] < NOTACHAR)
+ {
+ while (p[1] == p[0] + 1) p++;
+ n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1,
+ (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1);
+ p++;
+ }
+return n8;
+}
+
+
+
+/*************************************************
+* Find details of duplicate group names *
+*************************************************/
+
+/* This is called from compile_branch() when it needs to know the index and
+count of duplicates in the names table when processing named backreferences,
+either directly, or as conditions.
+
+Arguments:
+ name points to the name
+ length the length of the name
+ indexptr where to put the index
+ countptr where to put the count of duplicates
+ errorcodeptr where to put an error code
+ cb the compile block
+
+Returns: TRUE if OK, FALSE if not, error code set
+*/
+
+static BOOL
+find_dupname_details(PCRE2_SPTR name, uint32_t length, int *indexptr,
+ int *countptr, int *errorcodeptr, compile_block *cb)
+{
+uint32_t i, groupnumber;
+int count;
+PCRE2_UCHAR *slot = cb->name_table;
+
+/* Find the first entry in the table */
+
+for (i = 0; i < cb->names_found; i++)
+ {
+ if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) == 0 &&
+ slot[IMM2_SIZE+length] == 0) break;
+ slot += cb->name_entry_size;
+ }
+
+/* This should not occur, because this function is called only when we know we
+have duplicate names. Give an internal error. */
+
+if (i >= cb->names_found)
+ {
+ *errorcodeptr = ERR53;
+ cb->erroroffset = name - cb->start_pattern;
+ return FALSE;
+ }
+
+/* Record the index and then see how many duplicates there are, updating the
+backref map and maximum back reference as we do. */
+
+*indexptr = i;
+count = 0;
+
+for (;;)
+ {
+ count++;
+ groupnumber = GET2(slot,0);
+ cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
+ if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
+ if (++i >= cb->names_found) break;
+ slot += cb->name_entry_size;
+ if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) != 0 ||
+ (slot+IMM2_SIZE)[length] != 0) break;
+ }
+
+*countptr = count;
+return TRUE;
+}
+
+
+
+/*************************************************
+* Compile one branch *
+*************************************************/
+
+/* Scan the parsed pattern, compiling it into the a vector of PCRE2_UCHAR. If
+the options are changed during the branch, the pointer is used to change the
+external options bits. This function is used during the pre-compile phase when
+we are trying to find out the amount of memory needed, as well as during the
+real compile phase. The value of lengthptr distinguishes the two phases.
+
+Arguments:
+ optionsptr pointer to the option bits
+ codeptr points to the pointer to the current code point
+ pptrptr points to the current parsed pattern pointer
+ errorcodeptr points to error code variable
+ firstcuptr place to put the first required code unit
+ firstcuflagsptr place to put the first code unit flags, or a negative number
+ reqcuptr place to put the last required code unit
+ reqcuflagsptr place to put the last required code unit flags, or a negative number
+ bcptr points to current branch chain
+ cb contains pointers to tables etc.
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: 0 There's been an error, *errorcodeptr is non-zero
+ +1 Success, this branch must match at least one character
+ -1 Success, this branch may match an empty string
+*/
+
+static int
+compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr, uint32_t **pptrptr,
+ int *errorcodeptr, uint32_t *firstcuptr, int32_t *firstcuflagsptr,
+ uint32_t *reqcuptr, int32_t *reqcuflagsptr, branch_chain *bcptr,
+ compile_block *cb, PCRE2_SIZE *lengthptr)
+{
+int bravalue = 0;
+int okreturn = -1;
+int group_return = 0;
+uint32_t repeat_min = 0, repeat_max = 0; /* To please picky compilers */
+uint32_t greedy_default, greedy_non_default;
+uint32_t repeat_type, op_type;
+uint32_t options = *optionsptr; /* May change dynamically */
+uint32_t firstcu, reqcu;
+uint32_t zeroreqcu, zerofirstcu;
+uint32_t escape;
+uint32_t *pptr = *pptrptr;
+uint32_t meta, meta_arg;
+int32_t firstcuflags, reqcuflags;
+int32_t zeroreqcuflags, zerofirstcuflags;
+int32_t req_caseopt, reqvary, tempreqvary;
+PCRE2_SIZE offset = 0;
+PCRE2_SIZE length_prevgroup = 0;
+PCRE2_UCHAR *code = *codeptr;
+PCRE2_UCHAR *last_code = code;
+PCRE2_UCHAR *orig_code = code;
+PCRE2_UCHAR *tempcode;
+PCRE2_UCHAR *previous = NULL;
+PCRE2_UCHAR op_previous;
+BOOL groupsetfirstcu = FALSE;
+BOOL matched_char = FALSE;
+BOOL previous_matched_char = FALSE;
+const uint8_t *cbits = cb->cbits;
+uint8_t classbits[32];
+
+/* We can fish out the UTF setting once and for all into a BOOL, but we must
+not do this for other options (e.g. PCRE2_EXTENDED) because they may change
+dynamically as we process the pattern. */
+
+#ifdef SUPPORT_UNICODE
+BOOL utf = (options & PCRE2_UTF) != 0;
+#else /* No UTF support */
+BOOL utf = FALSE;
+#endif
+
+/* Helper variables for OP_XCLASS opcode (for characters > 255). We define
+class_uchardata always so that it can be passed to add_to_class() always,
+though it will not be used in non-UTF 8-bit cases. This avoids having to supply
+alternative calls for the different cases. */
+
+PCRE2_UCHAR *class_uchardata;
+#ifdef SUPPORT_WIDE_CHARS
+BOOL xclass;
+PCRE2_UCHAR *class_uchardata_base;
+#endif
+
+/* Set up the default and non-default settings for greediness */
+
+greedy_default = ((options & PCRE2_UNGREEDY) != 0);
+greedy_non_default = greedy_default ^ 1;
+
+/* Initialize no first unit, no required unit. REQ_UNSET means "no char
+matching encountered yet". It gets changed to REQ_NONE if we hit something that
+matches a non-fixed first unit; reqcu just remains unset if we never find one.
+
+When we hit a repeat whose minimum is zero, we may have to adjust these values
+to take the zero repeat into account. This is implemented by setting them to
+zerofirstcu and zeroreqcu when such a repeat is encountered. The individual
+item types that can be repeated set these backoff variables appropriately. */
+
+firstcu = reqcu = zerofirstcu = zeroreqcu = 0;
+firstcuflags = reqcuflags = zerofirstcuflags = zeroreqcuflags = REQ_UNSET;
+
+/* The variable req_caseopt contains either the REQ_CASELESS value or zero,
+according to the current setting of the caseless flag. The REQ_CASELESS value
+leaves the lower 28 bit empty. It is added into the firstcu or reqcu variables
+to record the case status of the value. This is used only for ASCII characters.
+*/
+
+req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS:0;
+
+/* Switch on next META item until the end of the branch */
+
+for (;; pptr++)
+ {
+#ifdef SUPPORT_WIDE_CHARS
+ BOOL xclass_has_prop;
+#endif
+ BOOL negate_class;
+ BOOL should_flip_negation;
+ BOOL match_all_or_no_wide_chars;
+ BOOL possessive_quantifier;
+ BOOL note_group_empty;
+ int class_has_8bitchar;
+ int i;
+ uint32_t mclength;
+ uint32_t templastcapture;
+ uint32_t skipunits;
+ uint32_t subreqcu, subfirstcu;
+ uint32_t groupnumber;
+ uint32_t verbarglen, verbculen;
+ int32_t subreqcuflags, subfirstcuflags; /* Must be signed */
+ open_capitem *oc;
+ PCRE2_UCHAR mcbuffer[8];
+
+ /* Get next META item in the pattern and its potential argument. */
+
+ meta = META_CODE(*pptr);
+ meta_arg = META_DATA(*pptr);
+
+ /* If we are in the pre-compile phase, accumulate the length used for the
+ previous cycle of this loop, unless the next item is a quantifier. */
+
+ if (lengthptr != NULL)
+ {
+ if (code > cb->start_workspace + cb->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
+ {
+ *errorcodeptr = (code >= cb->start_workspace + cb->workspace_size)?
+ ERR52 : ERR86;
+ return 0;
+ }
+
+ /* There is at least one situation where code goes backwards: this is the
+ case of a zero quantifier after a class (e.g. [ab]{0}). When the quantifier
+ is processed, the whole class is eliminated. However, it is created first,
+ so we have to allow memory for it. Therefore, don't ever reduce the length
+ at this point. */
+
+ if (code < last_code) code = last_code;
+
+ /* If the next thing is not a quantifier, we add the length of the previous
+ item into the total, and reset the code pointer to the start of the
+ workspace. Otherwise leave the previous item available to be quantified. */
+
+ if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
+ {
+ if (OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
+ {
+ *errorcodeptr = ERR20; /* Integer overflow */
+ return 0;
+ }
+ *lengthptr += (PCRE2_SIZE)(code - orig_code);
+ if (*lengthptr > MAX_PATTERN_SIZE)
+ {
+ *errorcodeptr = ERR20; /* Pattern is too large */
+ return 0;
+ }
+ code = orig_code;
+ }
+
+ /* Remember where this code item starts so we can catch the "backwards"
+ case above next time round. */
+
+ last_code = code;
+ }
+
+ /* Process the next parsed pattern item. If it is not a quantifier, remember
+ where it starts so that it can be quantified when a quantifier follows.
+ Checking for the legality of quantifiers happens in parse_regex(), except for
+ a quantifier after an assertion that is a condition. */
+
+ if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
+ {
+ previous = code;
+ if (matched_char) okreturn = 1;
+ }
+
+ previous_matched_char = matched_char;
+ matched_char = FALSE;
+ note_group_empty = FALSE;
+ skipunits = 0; /* Default value for most subgroups */
+
+ switch(meta)
+ {
+ /* ===================================================================*/
+ /* The branch terminates at pattern end or | or ) */
+
+ case META_END:
+ case META_ALT:
+ case META_KET:
+ *firstcuptr = firstcu;
+ *firstcuflagsptr = firstcuflags;
+ *reqcuptr = reqcu;
+ *reqcuflagsptr = reqcuflags;
+ *codeptr = code;
+ *pptrptr = pptr;
+ return okreturn;
+
+
+ /* ===================================================================*/
+ /* Handle single-character metacharacters. In multiline mode, ^ disables
+ the setting of any following char as a first character. */
+
+ case META_CIRCUMFLEX:
+ if ((options & PCRE2_MULTILINE) != 0)
+ {
+ if (firstcuflags == REQ_UNSET)
+ zerofirstcuflags = firstcuflags = REQ_NONE;
+ *code++ = OP_CIRCM;
+ }
+ else *code++ = OP_CIRC;
+ break;
+
+ case META_DOLLAR:
+ *code++ = ((options & PCRE2_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
+ break;
+
+ /* There can never be a first char if '.' is first, whatever happens about
+ repeats. The value of reqcu doesn't change either. */
+
+ case META_DOT:
+ matched_char = TRUE;
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ zerofirstcu = firstcu;
+ zerofirstcuflags = firstcuflags;
+ zeroreqcu = reqcu;
+ zeroreqcuflags = reqcuflags;
+ *code++ = ((options & PCRE2_DOTALL) != 0)? OP_ALLANY: OP_ANY;
+ break;
+
+
+ /* ===================================================================*/
+ /* Empty character classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set.
+ Otherwise, an initial ']' is taken as a data character. When empty classes
+ are allowed, [] must always fail, so generate OP_FAIL, whereas [^] must
+ match any character, so generate OP_ALLANY. */
+
+ case META_CLASS_EMPTY:
+ case META_CLASS_EMPTY_NOT:
+ matched_char = TRUE;
+ *code++ = (meta == META_CLASS_EMPTY_NOT)? OP_ALLANY : OP_FAIL;
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ zerofirstcu = firstcu;
+ zerofirstcuflags = firstcuflags;
+ break;
+
+
+ /* ===================================================================*/
+ /* Non-empty character class. If the included characters are all < 256, we
+ build a 32-byte bitmap of the permitted characters, except in the special
+ case where there is only one such character. For negated classes, we build
+ the map as usual, then invert it at the end. However, we use a different
+ opcode so that data characters > 255 can be handled correctly.
+
+ If the class contains characters outside the 0-255 range, a different
+ opcode is compiled. It may optionally have a bit map for characters < 256,
+ but those above are are explicitly listed afterwards. A flag code unit
+ tells whether the bitmap is present, and whether this is a negated class or
+ not. */
+
+ case META_CLASS_NOT:
+ case META_CLASS:
+ matched_char = TRUE;
+ negate_class = meta == META_CLASS_NOT;
+
+ /* We can optimize the case of a single character in a class by generating
+ OP_CHAR or OP_CHARI if it's positive, or OP_NOT or OP_NOTI if it's
+ negative. In the negative case there can be no first char if this item is
+ first, whatever repeat count may follow. In the case of reqcu, save the
+ previous value for reinstating. */
+
+ /* NOTE: at present this optimization is not effective if the only
+ character in a class in 32-bit, non-UCP mode has its top bit set. */
+
+ if (pptr[1] < META_END && pptr[2] == META_CLASS_END)
+ {
+#ifdef SUPPORT_UNICODE
+ uint32_t d;
+#endif
+ uint32_t c = pptr[1];
+
+ pptr += 2; /* Move on to class end */
+ if (meta == META_CLASS) /* A positive one-char class can be */
+ { /* handled as a normal literal character. */
+ meta = c; /* Set up the character */
+ goto NORMAL_CHAR_SET;
+ }
+
+ /* Handle a negative one-character class */
+
+ zeroreqcu = reqcu;
+ zeroreqcuflags = reqcuflags;
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ zerofirstcu = firstcu;
+ zerofirstcuflags = firstcuflags;
+
+ /* For caseless UTF mode, check whether this character has more than
+ one other case. If so, generate a special OP_NOTPROP item instead of
+ OP_NOTI. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf && (options & PCRE2_CASELESS) != 0 &&
+ (d = UCD_CASESET(c)) != 0)
+ {
+ *code++ = OP_NOTPROP;
+ *code++ = PT_CLIST;
+ *code++ = d;
+ break; /* We are finished with this class */
+ }
+#endif
+ /* Char has only one other case, or UCP not available */
+
+ *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT;
+ code += PUTCHAR(c, code);
+ break; /* We are finished with this class */
+ } /* End of 1-char optimization */
+
+ /* Handle character classes that contain more than just one literal
+ character. */
+
+ /* If a non-extended class contains a negative special such as \S, we need
+ to flip the negation flag at the end, so that support for characters > 255
+ works correctly (they are all included in the class). An extended class may
+ need to insert specific matching or non-matching code for wide characters.
+ */
+
+ should_flip_negation = match_all_or_no_wide_chars = FALSE;
+
+ /* Extended class (xclass) will be used when characters > 255
+ might match. */
+
+#ifdef SUPPORT_WIDE_CHARS
+ xclass = FALSE;
+ class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */
+ class_uchardata_base = class_uchardata; /* Save the start */
+#endif
+
+ /* For optimization purposes, we track some properties of the class:
+ class_has_8bitchar will be non-zero if the class contains at least one
+ character with a code point less than 256; xclass_has_prop will be TRUE if
+ Unicode property checks are present in the class. */
+
+ class_has_8bitchar = 0;
+#ifdef SUPPORT_WIDE_CHARS
+ xclass_has_prop = FALSE;
+#endif
+
+ /* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map
+ in a temporary bit of memory, in case the class contains fewer than two
+ 8-bit characters because in that case the compiled code doesn't use the bit
+ map. */
+
+ memset(classbits, 0, 32 * sizeof(uint8_t));
+
+ /* Process items until META_CLASS_END is reached. */
+
+ while ((meta = *(++pptr)) != META_CLASS_END)
+ {
+ /* Handle POSIX classes such as [:alpha:] etc. */
+
+ if (meta == META_POSIX || meta == META_POSIX_NEG)
+ {
+ BOOL local_negate = (meta == META_POSIX_NEG);
+ int posix_class = *(++pptr);
+ int taboffset, tabopt;
+ uint8_t pbits[32];
+
+ should_flip_negation = local_negate; /* Note negative special */
+
+ /* If matching is caseless, upper and lower are converted to alpha.
+ This relies on the fact that the class table starts with alpha,
+ lower, upper as the first 3 entries. */
+
+ if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2)
+ posix_class = 0;
+
+ /* When PCRE2_UCP is set, some of the POSIX classes are converted to
+ different escape sequences that use Unicode properties \p or \P.
+ Others that are not available via \p or \P have to generate
+ XCL_PROP/XCL_NOTPROP directly, which is done here. */
+
+#ifdef SUPPORT_UNICODE
+ if ((options & PCRE2_UCP) != 0) switch(posix_class)
+ {
+ case PC_GRAPH:
+ case PC_PRINT:
+ case PC_PUNCT:
+ *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;
+ *class_uchardata++ = (PCRE2_UCHAR)
+ ((posix_class == PC_GRAPH)? PT_PXGRAPH :
+ (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT);
+ *class_uchardata++ = 0;
+ xclass_has_prop = TRUE;
+ goto CONTINUE_CLASS;
+
+ /* For the other POSIX classes (ascii, xdigit) we are going to
+ fall through to the non-UCP case and build a bit map for
+ characters with code points less than 256. However, if we are in
+ a negated POSIX class, characters with code points greater than
+ 255 must either all match or all not match, depending on whether
+ the whole class is not or is negated. For example, for
+ [[:^ascii:]... they must all match, whereas for [^[:^xdigit:]...
+ they must not.
+
+ In the special case where there are no xclass items, this is
+ automatically handled by the use of OP_CLASS or OP_NCLASS, but an
+ explicit range is needed for OP_XCLASS. Setting a flag here
+ causes the range to be generated later when it is known that
+ OP_XCLASS is required. In the 8-bit library this is relevant only in
+ utf mode, since no wide characters can exist otherwise. */
+
+ default:
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (utf)
+#endif
+ match_all_or_no_wide_chars |= local_negate;
+ break;
+ }
+#endif /* SUPPORT_UNICODE */
+
+ /* In the non-UCP case, or when UCP makes no difference, we build the
+ bit map for the POSIX class in a chunk of local store because we may
+ be adding and subtracting from it, and we don't want to subtract bits
+ that may be in the main map already. At the end we or the result into
+ the bit map that is being built. */
+
+ posix_class *= 3;
+
+ /* Copy in the first table (always present) */
+
+ memcpy(pbits, cbits + posix_class_maps[posix_class],
+ 32 * sizeof(uint8_t));
+
+ /* If there is a second table, add or remove it as required. */
+
+ taboffset = posix_class_maps[posix_class + 1];
+ tabopt = posix_class_maps[posix_class + 2];
+
+ if (taboffset >= 0)
+ {
+ if (tabopt >= 0)
+ for (i = 0; i < 32; i++) pbits[i] |= cbits[(int)i + taboffset];
+ else
+ for (i = 0; i < 32; i++) pbits[i] &= ~cbits[(int)i + taboffset];
+ }
+
+ /* Now see if we need to remove any special characters. An option
+ value of 1 removes vertical space and 2 removes underscore. */
+
+ if (tabopt < 0) tabopt = -tabopt;
+ if (tabopt == 1) pbits[1] &= ~0x3c;
+ else if (tabopt == 2) pbits[11] &= 0x7f;
+
+ /* Add the POSIX table or its complement into the main table that is
+ being built and we are done. */
+
+ if (local_negate)
+ for (i = 0; i < 32; i++) classbits[i] |= ~pbits[i];
+ else
+ for (i = 0; i < 32; i++) classbits[i] |= pbits[i];
+
+ /* Every class contains at least one < 256 character. */
+
+ class_has_8bitchar = 1;
+ goto CONTINUE_CLASS; /* End of POSIX handling */
+ }
+
+ /* Other than POSIX classes, the only items we should encounter are
+ \d-type escapes and literal characters (possibly as ranges). */
+
+ if (meta == META_BIGVALUE)
+ {
+ meta = *(++pptr);
+ goto CLASS_LITERAL;
+ }
+
+ /* Any other non-literal must be an escape */
+
+ if (meta >= META_END)
+ {
+ if (META_CODE(meta) != META_ESCAPE)
+ {
+#ifdef DEBUG_SHOW_PARSED
+ fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x "
+ "in character class\n", meta);
+#endif
+ *errorcodeptr = ERR89; /* Internal error - unrecognized. */
+ return 0;
+ }
+ escape = META_DATA(meta);
+
+ /* Every class contains at least one < 256 character. */
+
+ class_has_8bitchar++;
+
+ switch(escape)
+ {
+ case ESC_d:
+ for (i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit];
+ break;
+
+ case ESC_D:
+ should_flip_negation = TRUE;
+ for (i = 0; i < 32; i++) classbits[i] |= ~cbits[i+cbit_digit];
+ break;
+
+ case ESC_w:
+ for (i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word];
+ break;
+
+ case ESC_W:
+ should_flip_negation = TRUE;
+ for (i = 0; i < 32; i++) classbits[i] |= ~cbits[i+cbit_word];
+ break;
+
+ /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl
+ 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was
+ previously set by something earlier in the character class.
+ Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so
+ we could just adjust the appropriate bit. From PCRE 8.34 we no
+ longer treat \s and \S specially. */
+
+ case ESC_s:
+ for (i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space];
+ break;
+
+ case ESC_S:
+ should_flip_negation = TRUE;
+ for (i = 0; i < 32; i++) classbits[i] |= ~cbits[i+cbit_space];
+ break;
+
+ /* When adding the horizontal or vertical space lists to a class, or
+ their complements, disable PCRE2_CASELESS, because it justs wastes
+ time, and in the "not-x" UTF cases can create unwanted duplicates in
+ the XCLASS list (provoked by characters that have more than one other
+ case and by both cases being in the same "not-x" sublist). */
+
+ case ESC_h:
+ (void)add_list_to_class(classbits, &class_uchardata,
+ options & ~PCRE2_CASELESS, cb, PRIV(hspace_list), NOTACHAR);
+ break;
+
+ case ESC_H:
+ (void)add_not_list_to_class(classbits, &class_uchardata,
+ options & ~PCRE2_CASELESS, cb, PRIV(hspace_list));
+ break;
+
+ case ESC_v:
+ (void)add_list_to_class(classbits, &class_uchardata,
+ options & ~PCRE2_CASELESS, cb, PRIV(vspace_list), NOTACHAR);
+ break;
+
+ case ESC_V:
+ (void)add_not_list_to_class(classbits, &class_uchardata,
+ options & ~PCRE2_CASELESS, cb, PRIV(vspace_list));
+ break;
+
+ case ESC_p:
+ case ESC_P:
+ {
+ uint32_t ptype = *(++pptr) >> 16;
+ uint32_t pdata = *pptr & 0xffff;
+ *class_uchardata++ = (escape == ESC_p)? XCL_PROP : XCL_NOTPROP;
+ *class_uchardata++ = ptype;
+ *class_uchardata++ = pdata;
+#ifdef SUPPORT_WIDE_CHARS
+ xclass_has_prop = TRUE;
+#endif
+ class_has_8bitchar--; /* Undo! */
+ }
+ break;
+ }
+
+ goto CONTINUE_CLASS;
+ } /* End handling \d-type escapes */
+
+ /* A literal character may be followed by a range meta. At parse time
+ there are checks for out-of-order characters, for ranges where the two
+ characters are equal, and for hyphens that cannot indicate a range. At
+ this point, therefore, no checking is needed. */
+
+ else
+ {
+ uint32_t c, d;
+
+ CLASS_LITERAL:
+ c = d = meta;
+
+ /* Remember if \r or \n were explicitly used */
+
+ if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF;
+
+ /* Process a character range */
+
+ if (pptr[1] == META_RANGE_LITERAL || pptr[1] == META_RANGE_ESCAPED)
+ {
+#ifdef EBCDIC
+ BOOL range_is_literal = (pptr[1] == META_RANGE_LITERAL);
+#endif
+ pptr += 2;
+ d = *pptr;
+ if (d == META_BIGVALUE) d = *(++pptr);
+
+ /* Remember an explicit \r or \n, and add the range to the class. */
+
+ if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF;
+
+ /* In an EBCDIC environment, Perl treats alphabetic ranges specially
+ because there are holes in the encoding, and simply using the range
+ A-Z (for example) would include the characters in the holes. This
+ applies only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */
+
+#ifdef EBCDIC
+ if (range_is_literal &&
+ (cb->ctypes[c] & ctype_letter) != 0 &&
+ (cb->ctypes[d] & ctype_letter) != 0 &&
+ (d <= CHAR_z) == (d <= CHAR_z))
+ {
+ uint32_t uc = (d <= CHAR_z)? 0 : 64;
+ uint32_t C = d - uc;
+ uint32_t D = d - uc;
+
+ if (C <= CHAR_i)
+ {
+ class_has_8bitchar +=
+ add_to_class(classbits, &class_uchardata, options, cb, C + uc,
+ ((D < CHAR_i)? D : CHAR_i) + uc);
+ C = CHAR_j;
+ }
+
+ if (C <= D && C <= CHAR_r)
+ {
+ class_has_8bitchar +=
+ add_to_class(classbits, &class_uchardata, options, cb, C + uc,
+ ((D < CHAR_r)? D : CHAR_r) + uc);
+ C = CHAR_s;
+ }
+
+ if (C <= D)
+ {
+ class_has_8bitchar +=
+ add_to_class(classbits, &class_uchardata, options, cb, C + uc,
+ D + uc);
+ }
+ }
+ else
+#endif
+ /* Not an EBCDIC special range */
+
+ class_has_8bitchar +=
+ add_to_class(classbits, &class_uchardata, options, cb, c, d);
+ goto CONTINUE_CLASS; /* Go get the next char in the class */
+ } /* End of range handling */
+
+
+ /* Handle a single character. */
+
+ class_has_8bitchar +=
+ add_to_class(classbits, &class_uchardata, options, cb, meta, meta);
+ }
+
+ /* Continue to the next item in the class. */
+
+ CONTINUE_CLASS:
+
+#ifdef SUPPORT_WIDE_CHARS
+ /* If any wide characters or Unicode properties have been encountered,
+ set xclass = TRUE. Then, in the pre-compile phase, accumulate the length
+ of the extra data and reset the pointer. This is so that very large
+ classes that contain a zillion wide characters or Unicode property tests
+ do not overwrite the work space (which is on the stack). */
+
+ if (class_uchardata > class_uchardata_base)
+ {
+ xclass = TRUE;
+ if (lengthptr != NULL)
+ {
+ *lengthptr += class_uchardata - class_uchardata_base;
+ class_uchardata = class_uchardata_base;
+ }
+ }
+#endif
+
+ continue; /* Needed to avoid error when not supporting wide chars */
+ } /* End of main class-processing loop */
+
+ /* If this class is the first thing in the branch, there can be no first
+ char setting, whatever the repeat count. Any reqcu setting must remain
+ unchanged after any kind of repeat. */
+
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ zerofirstcu = firstcu;
+ zerofirstcuflags = firstcuflags;
+ zeroreqcu = reqcu;
+ zeroreqcuflags = reqcuflags;
+
+ /* If there are characters with values > 255, or Unicode property settings
+ (\p or \P), we have to compile an extended class, with its own opcode,
+ unless there were no property settings and there was a negated special such
+ as \S in the class, and PCRE2_UCP is not set, because in that case all
+ characters > 255 are in or not in the class, so any that were explicitly
+ given as well can be ignored.
+
+ In the UCP case, if certain negated POSIX classes ([:^ascii:] or
+ [^:xdigit:]) were present in a class, we either have to match or not match
+ all wide characters (depending on whether the whole class is or is not
+ negated). This requirement is indicated by match_all_or_no_wide_chars being
+ true. We do this by including an explicit range, which works in both cases.
+ This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there
+ cannot be any wide characters in 8-bit non-UTF mode.
+
+ When there *are* properties in a positive UTF-8 or any 16-bit or 32_bit
+ class where \S etc is present without PCRE2_UCP, causing an extended class
+ to be compiled, we make sure that all characters > 255 are included by
+ forcing match_all_or_no_wide_chars to be true.
+
+ If, when generating an xclass, there are no characters < 256, we can omit
+ the bitmap in the actual compiled code. */
+
+#ifdef SUPPORT_WIDE_CHARS /* Defined for 16/32 bits, or 8-bit with Unicode */
+ if (xclass && (
+#ifdef SUPPORT_UNICODE
+ (options & PCRE2_UCP) != 0 ||
+#endif
+ xclass_has_prop || !should_flip_negation))
+ {
+ if (match_all_or_no_wide_chars || (
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ utf &&
+#endif
+ should_flip_negation && !negate_class && (options & PCRE2_UCP) == 0))
+ {
+ *class_uchardata++ = XCL_RANGE;
+ if (utf) /* Will always be utf in the 8-bit library */
+ {
+ class_uchardata += PRIV(ord2utf)(0x100, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(MAX_UTF_CODE_POINT, class_uchardata);
+ }
+ else /* Can only happen for the 16-bit & 32-bit libraries */
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 16
+ *class_uchardata++ = 0x100;
+ *class_uchardata++ = 0xffffu;
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+ *class_uchardata++ = 0x100;
+ *class_uchardata++ = 0xffffffffu;
+#endif
+ }
+ }
+ *class_uchardata++ = XCL_END; /* Marks the end of extra data */
+ *code++ = OP_XCLASS;
+ code += LINK_SIZE;
+ *code = negate_class? XCL_NOT:0;
+ if (xclass_has_prop) *code |= XCL_HASPROP;
+
+ /* If the map is required, move up the extra data to make room for it;
+ otherwise just move the code pointer to the end of the extra data. */
+
+ if (class_has_8bitchar > 0)
+ {
+ *code++ |= XCL_MAP;
+ memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,
+ CU2BYTES(class_uchardata - code));
+ if (negate_class && !xclass_has_prop)
+ for (i = 0; i < 32; i++) classbits[i] = ~classbits[i];
+ memcpy(code, classbits, 32);
+ code = class_uchardata + (32 / sizeof(PCRE2_UCHAR));
+ }
+ else code = class_uchardata;
+
+ /* Now fill in the complete length of the item */
+
+ PUT(previous, 1, (int)(code - previous));
+ break; /* End of class handling */
+ }
+#endif /* SUPPORT_WIDE_CHARS */
+
+ /* If there are no characters > 255, or they are all to be included or
+ excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
+ whole class was negated and whether there were negative specials such as \S
+ (non-UCP) in the class. Then copy the 32-byte map into the code vector,
+ negating it if necessary. */
+
+ *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
+ if (lengthptr == NULL) /* Save time in the pre-compile phase */
+ {
+ if (negate_class)
+ for (i = 0; i < 32; i++) classbits[i] = ~classbits[i];
+ memcpy(code, classbits, 32);
+ }
+ code += 32 / sizeof(PCRE2_UCHAR);
+ break; /* End of class processing */
+
+
+ /* ===================================================================*/
+ /* Deal with (*VERB)s. */
+
+ /* Check for open captures before ACCEPT and convert it to ASSERT_ACCEPT if
+ in an assertion. In the first pass, just accumulate the length required;
+ otherwise hitting (*ACCEPT) inside many nested parentheses can cause
+ workspace overflow. Do not set firstcu after *ACCEPT. */
+
+ case META_ACCEPT:
+ cb->had_accept = TRUE;
+ for (oc = cb->open_caps; oc != NULL; oc = oc->next)
+ {
+ if (lengthptr != NULL)
+ {
+ *lengthptr += CU2BYTES(1) + IMM2_SIZE;
+ }
+ else
+ {
+ *code++ = OP_CLOSE;
+ PUT2INC(code, 0, oc->number);
+ }
+ }
+ *code++ = (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ break;
+
+ case META_PRUNE:
+ case META_SKIP:
+ cb->had_pruneorskip = TRUE;
+ /* Fall through */
+ case META_COMMIT:
+ case META_FAIL:
+ *code++ = verbops[(meta - META_MARK) >> 16];
+ break;
+
+ case META_THEN:
+ cb->external_flags |= PCRE2_HASTHEN;
+ *code++ = OP_THEN;
+ break;
+
+ /* Handle verbs with arguments. Arguments can be very long, especially in
+ 16- and 32-bit modes, and can overflow the workspace in the first pass.
+ However, the argument length is constrained to be small enough to fit in
+ one code unit. This check happens in parse_regex(). In the first pass,
+ instead of putting the argument into memory, we just update the length
+ counter and set up an empty argument. */
+
+ case META_THEN_ARG:
+ cb->external_flags |= PCRE2_HASTHEN;
+ goto VERB_ARG;
+
+ case META_PRUNE_ARG:
+ case META_SKIP_ARG:
+ cb->had_pruneorskip = TRUE;
+ /* Fall through */
+ case META_MARK:
+ VERB_ARG:
+ *code++ = verbops[(meta - META_MARK) >> 16];
+ /* The length is in characters. */
+ verbarglen = *(++pptr);
+ verbculen = 0;
+ tempcode = code++;
+ for (i = 0; i < (int)verbarglen; i++)
+ {
+ meta = *(++pptr);
+#ifdef SUPPORT_UNICODE
+ if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else
+#endif
+ {
+ mclength = 1;
+ mcbuffer[0] = meta;
+ }
+ if (lengthptr != NULL) *lengthptr += mclength; else
+ {
+ memcpy(code, mcbuffer, CU2BYTES(mclength));
+ code += mclength;
+ verbculen += mclength;
+ }
+ }
+
+ *tempcode = verbculen; /* Fill in the code unit length */
+ *code++ = 0; /* Terminating zero */
+ break;
+
+
+ /* ===================================================================*/
+ /* Handle options change. The new setting must be passed back for use in
+ subsequent branches. Reset the greedy defaults and the case value for
+ firstcu and reqcu. */
+
+ case META_OPTIONS:
+ *optionsptr = options = *(++pptr);
+ greedy_default = ((options & PCRE2_UNGREEDY) != 0);
+ greedy_non_default = greedy_default ^ 1;
+ req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0;
+ break;
+
+
+ /* ===================================================================*/
+ /* Handle conditional subpatterns. The case of (?(Rdigits) is ambiguous
+ because it could be a numerical check on recursion, or a name check on a
+ group's being set. The pre-pass sets up META_COND_RNUMBER as a name so that
+ we can handle it either way. We first try for a name; if not found, process
+ the number. */
+
+ case META_COND_RNUMBER: /* (?(Rdigits) */
+ case META_COND_NAME: /* (?(name) or (?'name') or ?(<name>) */
+ case META_COND_RNAME: /* (?(R&name) - test for recursion */
+ bravalue = OP_COND;
+ {
+ int count, index;
+ PCRE2_SPTR name;
+ named_group *ng = cb->named_groups;
+ uint32_t length = *(++pptr);
+
+ GETPLUSOFFSET(offset, pptr);
+ name = cb->start_pattern + offset;
+
+ /* In the first pass, the names generated in the pre-pass are available,
+ but the main name table has not yet been created. Scan the list of names
+ generated in the pre-pass in order to get a number and whether or not
+ this name is duplicated. If it is not duplicated, we can handle it as a
+ numerical group. */
+
+ for (i = 0; i < cb->names_found; i++, ng++)
+ {
+ if (length == ng->length &&
+ PRIV(strncmp)(name, ng->name, length) == 0)
+ {
+ if (!ng->isdup)
+ {
+ code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;
+ PUT2(code, 2+LINK_SIZE, ng->number);
+ if (ng->number > cb->top_backref) cb->top_backref = ng->number;
+ skipunits = 1+IMM2_SIZE;
+ goto GROUP_PROCESS_NOTE_EMPTY;
+ }
+ break; /* Found a duplicated name */
+ }
+ }
+
+ /* If the name was not found we have a bad reference, unless we are
+ dealing with R<digits>, which is treated as a recursion test by number.
+ */
+
+ if (i >= cb->names_found)
+ {
+ groupnumber = 0;
+ if (meta == META_COND_RNUMBER)
+ {
+ for (i = 1; i < (int)length; i++)
+ {
+ groupnumber = groupnumber * 10 + name[i] - CHAR_0;
+ if (groupnumber > MAX_GROUP_NUMBER)
+ {
+ *errorcodeptr = ERR61;
+ cb->erroroffset = offset + i;
+ return 0;
+ }
+ }
+ }
+
+ if (meta != META_COND_RNUMBER || groupnumber > cb->bracount)
+ {
+ *errorcodeptr = ERR15;
+ cb->erroroffset = offset;
+ return 0;
+ }
+
+ /* (?Rdigits) treated as a recursion reference by number. A value of
+ zero (which is the result of both (?R) and (?R0)) means "any", and is
+ translated into RREF_ANY (which is 0xffff). */
+
+ if (groupnumber == 0) groupnumber = RREF_ANY;
+ code[1+LINK_SIZE] = OP_RREF;
+ PUT2(code, 2+LINK_SIZE, groupnumber);
+ skipunits = 1+IMM2_SIZE;
+ goto GROUP_PROCESS_NOTE_EMPTY;
+ }
+
+ /* A duplicated name was found. Note that if an R<digits> name is found
+ (META_COND_RNUMBER), it is a reference test, not a recursion test. */
+
+ code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;
+
+ /* We have a duplicated name. In the compile pass we have to search the
+ main table in order to get the index and count values. */
+
+ count = 0; /* Values for first pass (avoids compiler warning) */
+ index = 0;
+ if (lengthptr == NULL && !find_dupname_details(name, length, &index,
+ &count, errorcodeptr, cb)) return 0;
+
+ /* Add one to the opcode to change CREF/RREF into DNCREF/DNRREF and
+ insert appropriate data values. */
+
+ code[1+LINK_SIZE]++;
+ skipunits = 1+2*IMM2_SIZE;
+ PUT2(code, 2+LINK_SIZE, index);
+ PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count);
+ }
+ goto GROUP_PROCESS_NOTE_EMPTY;
+
+ /* The DEFINE condition is always false. It's internal groups may never
+ be called, so matched_char must remain false, hence the jump to
+ GROUP_PROCESS rather than GROUP_PROCESS_NOTE_EMPTY. */
+
+ case META_COND_DEFINE:
+ bravalue = OP_COND;
+ GETPLUSOFFSET(offset, pptr);
+ code[1+LINK_SIZE] = OP_DEFINE;
+ skipunits = 1;
+ goto GROUP_PROCESS;
+
+ /* Conditional test of a group's being set. */
+
+ case META_COND_NUMBER:
+ bravalue = OP_COND;
+ GETPLUSOFFSET(offset, pptr);
+ groupnumber = *(++pptr);
+ if (groupnumber > cb->bracount)
+ {
+ *errorcodeptr = ERR15;
+ cb->erroroffset = offset;
+ return 0;
+ }
+ if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
+ offset -= 2; /* Point at initial ( for too many branches error */
+ code[1+LINK_SIZE] = OP_CREF;
+ skipunits = 1+IMM2_SIZE;
+ PUT2(code, 2+LINK_SIZE, groupnumber);
+ goto GROUP_PROCESS_NOTE_EMPTY;
+
+ /* Test for the PCRE2 version. */
+
+ case META_COND_VERSION:
+ bravalue = OP_COND;
+ if (pptr[1] > 0)
+ code[1+LINK_SIZE] = ((PCRE2_MAJOR > pptr[2]) ||
+ (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR >= pptr[3]))?
+ OP_TRUE : OP_FALSE;
+ else
+ code[1+LINK_SIZE] = (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR == pptr[3])?
+ OP_TRUE : OP_FALSE;
+ skipunits = 1;
+ pptr += 3;
+ goto GROUP_PROCESS_NOTE_EMPTY;
+
+ /* The condition is an assertion, possibly preceded by a callout. */
+
+ case META_COND_ASSERT:
+ bravalue = OP_COND;
+ goto GROUP_PROCESS_NOTE_EMPTY;
+
+
+ /* ===================================================================*/
+ /* Handle all kinds of nested bracketed groups. The non-capturing,
+ non-conditional cases are here; others come to GROUP_PROCESS via goto. */
+
+ case META_LOOKAHEAD:
+ bravalue = OP_ASSERT;
+ cb->assert_depth += 1;
+ goto GROUP_PROCESS;
+
+ /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird
+ thing to do, but Perl allows all assertions to be quantified, and when
+ they contain capturing parentheses there may be a potential use for
+ this feature. Not that that applies to a quantified (?!) but we allow
+ it for uniformity. */
+
+ case META_LOOKAHEADNOT:
+ if (pptr[1] == META_KET &&
+ (pptr[2] < META_ASTERISK || pptr[2] > META_MINMAX_QUERY))
+ {
+ *code++ = OP_FAIL;
+ pptr++;
+ }
+ else
+ {
+ bravalue = OP_ASSERT_NOT;
+ cb->assert_depth += 1;
+ goto GROUP_PROCESS;
+ }
+ break;
+
+ case META_LOOKBEHIND:
+ bravalue = OP_ASSERTBACK;
+ cb->assert_depth += 1;
+ goto GROUP_PROCESS;
+
+ case META_LOOKBEHINDNOT:
+ bravalue = OP_ASSERTBACK_NOT;
+ cb->assert_depth += 1;
+ goto GROUP_PROCESS;
+
+ case META_ATOMIC:
+ bravalue = OP_ONCE;
+ goto GROUP_PROCESS_NOTE_EMPTY;
+
+ case META_NOCAPTURE:
+ bravalue = OP_BRA;
+ /* Fall through */
+
+ /* Process nested bracketed regex. The nesting depth is maintained for the
+ benefit of the stackguard function. The test for too deep nesting is now
+ done in parse_regex(). Assertion and DEFINE groups come to GROUP_PROCESS;
+ others come to GROUP_PROCESS_NOTE_EMPTY, to indicate that we need to take
+ note of whether or not they may match an empty string. */
+
+ GROUP_PROCESS_NOTE_EMPTY:
+ note_group_empty = TRUE;
+
+ GROUP_PROCESS:
+ cb->parens_depth += 1;
+ *code = bravalue;
+ pptr++;
+ tempcode = code;
+ tempreqvary = cb->req_varyopt; /* Save value before group */
+ templastcapture = cb->lastcapture; /* Save value before group */
+ length_prevgroup = 0; /* Initialize for pre-compile phase */
+
+ if ((group_return =
+ compile_regex(
+ options, /* The option state */
+ &tempcode, /* Where to put code (updated) */
+ &pptr, /* Input pointer (updated) */
+ errorcodeptr, /* Where to put an error message */
+ skipunits, /* Skip over bracket number */
+ &subfirstcu, /* For possible first char */
+ &subfirstcuflags,
+ &subreqcu, /* For possible last char */
+ &subreqcuflags,
+ bcptr, /* Current branch chain */
+ cb, /* Compile data block */
+ (lengthptr == NULL)? NULL : /* Actual compile phase */
+ &length_prevgroup /* Pre-compile phase */
+ )) == 0)
+ return 0; /* Error */
+
+ cb->parens_depth -= 1;
+
+ /* If that was a non-conditional significant group (not an assertion, not a
+ DEFINE) that matches at least one character, then the current item matches
+ a character. Conditionals are handled below. */
+
+ if (note_group_empty && bravalue != OP_COND && group_return > 0)
+ matched_char = TRUE;
+
+ /* If that was an atomic group and there are no capturing groups within it,
+ generate OP_ONCE_NC instead of OP_ONCE. */
+
+ if (bravalue == OP_ONCE && cb->lastcapture <= templastcapture)
+ *code = OP_ONCE_NC;
+
+ /* If we've just compiled an assertion, pop the assert depth. */
+
+ if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
+ cb->assert_depth -= 1;
+
+ /* At the end of compiling, code is still pointing to the start of the
+ group, while tempcode has been updated to point past the end of the group.
+ The parsed pattern pointer (pptr) is on the closing META_KET.
+
+ If this is a conditional bracket, check that there are no more than
+ two branches in the group, or just one if it's a DEFINE group. We do this
+ in the real compile phase, not in the pre-pass, where the whole group may
+ not be available. */
+
+ if (bravalue == OP_COND && lengthptr == NULL)
+ {
+ PCRE2_UCHAR *tc = code;
+ int condcount = 0;
+
+ do {
+ condcount++;
+ tc += GET(tc,1);
+ }
+ while (*tc != OP_KET);
+
+ /* A DEFINE group is never obeyed inline (the "condition" is always
+ false). It must have only one branch. Having checked this, change the
+ opcode to OP_FALSE. */
+
+ if (code[LINK_SIZE+1] == OP_DEFINE)
+ {
+ if (condcount > 1)
+ {
+ cb->erroroffset = offset;
+ *errorcodeptr = ERR54;
+ return 0;
+ }
+ code[LINK_SIZE+1] = OP_FALSE;
+ bravalue = OP_DEFINE; /* A flag to suppress char handling below */
+ }
+
+ /* A "normal" conditional group. If there is just one branch, we must not
+ make use of its firstcu or reqcu, because this is equivalent to an
+ empty second branch. Also, it may match an empty string. If there are two
+ branches, this item must match a character if the group must. */
+
+ else
+ {
+ if (condcount > 2)
+ {
+ cb->erroroffset = offset;
+ *errorcodeptr = ERR27;
+ return 0;
+ }
+ if (condcount == 1) subfirstcuflags = subreqcuflags = REQ_NONE;
+ else if (group_return > 0) matched_char = TRUE;
+ }
+ }
+
+ /* In the pre-compile phase, update the length by the length of the group,
+ less the brackets at either end. Then reduce the compiled code to just a
+ set of non-capturing brackets so that it doesn't use much memory if it is
+ duplicated by a quantifier.*/
+
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
+ {
+ *errorcodeptr = ERR20;
+ return 0;
+ }
+ *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
+ code++; /* This already contains bravalue */
+ PUTINC(code, 0, 1 + LINK_SIZE);
+ *code++ = OP_KET;
+ PUTINC(code, 0, 1 + LINK_SIZE);
+ break; /* No need to waste time with special character handling */
+ }
+
+ /* Otherwise update the main code pointer to the end of the group. */
+
+ code = tempcode;
+
+ /* For a DEFINE group, required and first character settings are not
+ relevant. */
+
+ if (bravalue == OP_DEFINE) break;
+
+ /* Handle updating of the required and first code units for other types of
+ group. Update for normal brackets of all kinds, and conditions with two
+ branches (see code above). If the bracket is followed by a quantifier with
+ zero repeat, we have to back off. Hence the definition of zeroreqcu and
+ zerofirstcu outside the main loop so that they can be accessed for the back
+ off. */
+
+ zeroreqcu = reqcu;
+ zeroreqcuflags = reqcuflags;
+ zerofirstcu = firstcu;
+ zerofirstcuflags = firstcuflags;
+ groupsetfirstcu = FALSE;
+
+ if (bravalue >= OP_ONCE) /* Not an assertion */
+ {
+ /* If we have not yet set a firstcu in this branch, take it from the
+ subpattern, remembering that it was set here so that a repeat of more
+ than one can replicate it as reqcu if necessary. If the subpattern has
+ no firstcu, set "none" for the whole branch. In both cases, a zero
+ repeat forces firstcu to "none". */
+
+ if (firstcuflags == REQ_UNSET && subfirstcuflags != REQ_UNSET)
+ {
+ if (subfirstcuflags >= 0)
+ {
+ firstcu = subfirstcu;
+ firstcuflags = subfirstcuflags;
+ groupsetfirstcu = TRUE;
+ }
+ else firstcuflags = REQ_NONE;
+ zerofirstcuflags = REQ_NONE;
+ }
+
+ /* If firstcu was previously set, convert the subpattern's firstcu
+ into reqcu if there wasn't one, using the vary flag that was in
+ existence beforehand. */
+
+ else if (subfirstcuflags >= 0 && subreqcuflags < 0)
+ {
+ subreqcu = subfirstcu;
+ subreqcuflags = subfirstcuflags | tempreqvary;
+ }
+
+ /* If the subpattern set a required code unit (or set a first code unit
+ that isn't really the first code unit - see above), set it. */
+
+ if (subreqcuflags >= 0)
+ {
+ reqcu = subreqcu;
+ reqcuflags = subreqcuflags;
+ }
+ }
+
+ /* For a forward assertion, we take the reqcu, if set, provided that the
+ group has also set a firstcu. This can be helpful if the pattern that
+ follows the assertion doesn't set a different char. For example, it's
+ useful for /(?=abcde).+/. We can't set firstcu for an assertion, however
+ because it leads to incorrect effect for patterns such as /(?=a)a.+/ when
+ the "real" "a" would then become a reqcu instead of a firstcu. This is
+ overcome by a scan at the end if there's no firstcu, looking for an
+ asserted first char. A similar effect for patterns like /(?=.*X)X$/ means
+ we must only take the reqcu when the group also set a firstcu. Otherwise,
+ in that example, 'X' ends up set for both. */
+
+ else if (bravalue == OP_ASSERT && subreqcuflags >= 0 &&
+ subfirstcuflags >= 0)
+ {
+ reqcu = subreqcu;
+ reqcuflags = subreqcuflags;
+ }
+
+ break; /* End of nested group handling */
+
+
+ /* ===================================================================*/
+ /* Handle named backreferences and recursions. */
+
+ case META_BACKREF_BYNAME:
+ case META_RECURSE_BYNAME:
+ {
+ int count, index;
+ PCRE2_SPTR name;
+ BOOL is_dupname = FALSE;
+ named_group *ng = cb->named_groups;
+ uint32_t length = *(++pptr);
+
+ GETPLUSOFFSET(offset, pptr);
+ name = cb->start_pattern + offset;
+
+ /* In the first pass, the names generated in the pre-pass are available,
+ but the main name table has not yet been created. Scan the list of names
+ generated in the pre-pass in order to get a number and whether or not
+ this name is duplicated. */
+
+ groupnumber = 0;
+ for (i = 0; i < cb->names_found; i++, ng++)
+ {
+ if (length == ng->length &&
+ PRIV(strncmp)(name, ng->name, length) == 0)
+ {
+ is_dupname = ng->isdup;
+ groupnumber = ng->number;
+
+ /* For a recursion, that's all that is needed. We can now go to
+ the code above that handles numerical recursion, applying it to
+ the first group with the given name. */
+
+ if (meta == META_RECURSE_BYNAME)
+ {
+ meta_arg = groupnumber;
+ goto HANDLE_NUMERICAL_RECURSION;
+ }
+
+ /* For a back reference, update the back reference map and the
+ maximum back reference. Then, for each group, we must check to
+ see if it is recursive, that is, it is inside the group that it
+ references. A flag is set so that the group can be made atomic.
+ */
+
+ cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
+ if (groupnumber > cb->top_backref)
+ cb->top_backref = groupnumber;
+
+ for (oc = cb->open_caps; oc != NULL; oc = oc->next)
+ {
+ if (oc->number == groupnumber)
+ {
+ oc->flag = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ /* If the name was not found we have a bad reference. */
+
+ if (groupnumber == 0)
+ {
+ *errorcodeptr = ERR15;
+ cb->erroroffset = offset;
+ return 0;
+ }
+
+ /* If a back reference name is not duplicated, we can handle it as
+ a numerical reference. */
+
+ if (!is_dupname)
+ {
+ meta_arg = groupnumber;
+ goto HANDLE_SINGLE_REFERENCE;
+ }
+
+ /* If a back reference name is duplicated, we generate a different
+ opcode to a numerical back reference. In the second pass we must
+ search for the index and count in the final name table. */
+
+ count = 0; /* Values for first pass (avoids compiler warning) */
+ index = 0;
+ if (lengthptr == NULL && !find_dupname_details(name, length, &index,
+ &count, errorcodeptr, cb)) return 0;
+
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
+ PUT2INC(code, 0, index);
+ PUT2INC(code, 0, count);
+ }
+ break;
+
+
+ /* ===================================================================*/
+ /* Handle a numerical callout. */
+
+ case META_CALLOUT_NUMBER:
+ code[0] = OP_CALLOUT;
+ PUT(code, 1, pptr[1]); /* Offset to next pattern item */
+ PUT(code, 1 + LINK_SIZE, pptr[2]); /* Length of next pattern item */
+ code[1 + 2*LINK_SIZE] = pptr[3];
+ pptr += 3;
+ code += PRIV(OP_lengths)[OP_CALLOUT];
+ break;
+
+
+ /* ===================================================================*/
+ /* Handle a callout with a string argument. In the pre-pass we just compute
+ the length without generating anything. The length in pptr[3] includes both
+ delimiters; in the actual compile only the first one is copied, but a
+ terminating zero is added. Any doubled delimiters within the string make
+ this an overestimate, but it is not worth bothering about. */
+
+ case META_CALLOUT_STRING:
+ if (lengthptr != NULL)
+ {
+ *lengthptr += pptr[3] + (1 + 4*LINK_SIZE);
+ pptr += 3;
+ SKIPOFFSET(pptr);
+ }
+
+ /* In the real compile we can copy the string. The starting delimiter is
+ included so that the client can discover it if they want. We also pass the
+ start offset to help a script language give better error messages. */
+
+ else
+ {
+ PCRE2_SPTR pp;
+ uint32_t delimiter;
+ uint32_t length = pptr[3];
+ PCRE2_UCHAR *callout_string = code + (1 + 4*LINK_SIZE);
+
+ code[0] = OP_CALLOUT_STR;
+ PUT(code, 1, pptr[1]); /* Offset to next pattern item */
+ PUT(code, 1 + LINK_SIZE, pptr[2]); /* Length of next pattern item */
+
+ pptr += 3;
+ GETPLUSOFFSET(offset, pptr); /* Offset to string in pattern */
+ pp = cb->start_pattern + offset;
+ delimiter = *callout_string++ = *pp++;
+ if (delimiter == CHAR_LEFT_CURLY_BRACKET)
+ delimiter = CHAR_RIGHT_CURLY_BRACKET;
+ PUT(code, 1 + 3*LINK_SIZE, (int)(offset + 1)); /* One after delimiter */
+
+ /* The syntax of the pattern was checked in the parsing scan. The length
+ includes both delimiters, but we have passed the opening one just above,
+ so we reduce length before testing it. The test is for > 1 because we do
+ not want to copy the final delimiter. This also ensures that pp[1] is
+ accessible. */
+
+ while (--length > 1)
+ {
+ if (*pp == delimiter && pp[1] == delimiter)
+ {
+ *callout_string++ = delimiter;
+ pp += 2;
+ length--;
+ }
+ else *callout_string++ = *pp++;
+ }
+ *callout_string++ = CHAR_NULL;
+
+ /* Set the length of the entire item, the advance to its end. */
+
+ PUT(code, 1 + 2*LINK_SIZE, (int)(callout_string - code));
+ code = callout_string;
+ }
+ break;
+
+
+ /* ===================================================================*/
+ /* Handle repetition. The different types are all sorted out in the parsing
+ pass. */
+
+ case META_MINMAX_PLUS:
+ case META_MINMAX_QUERY:
+ case META_MINMAX:
+ repeat_min = *(++pptr);
+ repeat_max = *(++pptr);
+ goto REPEAT;
+
+ case META_ASTERISK:
+ case META_ASTERISK_PLUS:
+ case META_ASTERISK_QUERY:
+ repeat_min = 0;
+ repeat_max = REPEAT_UNLIMITED;
+ goto REPEAT;
+
+ case META_PLUS:
+ case META_PLUS_PLUS:
+ case META_PLUS_QUERY:
+ repeat_min = 1;
+ repeat_max = REPEAT_UNLIMITED;
+ goto REPEAT;
+
+ case META_QUERY:
+ case META_QUERY_PLUS:
+ case META_QUERY_QUERY:
+ repeat_min = 0;
+ repeat_max = 1;
+
+ REPEAT:
+ if (previous_matched_char && repeat_min > 0) matched_char = TRUE;
+
+ /* Remember whether this is a variable length repeat, and default to
+ single-char opcodes. */
+
+ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
+ op_type = 0;
+
+ /* If the repeat is {1} we can ignore it. */
+
+ if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
+
+ /* Adjust first and required code units for a zero repeat. */
+
+ if (repeat_min == 0)
+ {
+ firstcu = zerofirstcu;
+ firstcuflags = zerofirstcuflags;
+ reqcu = zeroreqcu;
+ reqcuflags = zeroreqcuflags;
+ }
+
+ /* Note the greediness and possessiveness. */
+
+ switch (meta)
+ {
+ case META_MINMAX_PLUS:
+ case META_ASTERISK_PLUS:
+ case META_PLUS_PLUS:
+ case META_QUERY_PLUS:
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ break;
+
+ case META_MINMAX_QUERY:
+ case META_ASTERISK_QUERY:
+ case META_PLUS_QUERY:
+ case META_QUERY_QUERY:
+ repeat_type = greedy_non_default;
+ possessive_quantifier = FALSE;
+ break;
+
+ default:
+ repeat_type = greedy_default;
+ possessive_quantifier = FALSE;
+ break;
+ }
+
+ /* Save start of previous item, in case we have to move it up in order to
+ insert something before it, and remember what it was. */
+
+ tempcode = previous;
+ op_previous = *previous;
+
+ /* If previous was a recursion call, wrap it in atomic brackets so that
+ previous becomes the atomic group. All recursions were so wrapped in the
+ past, but it no longer happens for non-repeated recursions. In fact, the
+ repeated ones could be re-implemented independently so as not to need this,
+ but for the moment we rely on the code for repeating groups. */
+
+ if (op_previous == OP_RECURSE)
+ {
+ memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE));
+ op_previous = *previous = OP_ONCE;
+ PUT(previous, 1, 2 + 2*LINK_SIZE);
+ previous[2 + 2*LINK_SIZE] = OP_KET;
+ PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
+ code += 2 + 2 * LINK_SIZE;
+ length_prevgroup = 3 + 3*LINK_SIZE;
+ group_return = -1; /* Set "may match empty string" */
+ }
+
+ /* Now handle repetition for the different types of item. */
+
+ switch (op_previous)
+ {
+ /* If previous was a character or negated character match, abolish the
+ item and generate a repeat item instead. If a char item has a minimum of
+ more than one, ensure that it is set in reqcu - it might not be if a
+ sequence such as x{3} is the first thing in a branch because the x will
+ have gone into firstcu instead. */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ op_type = chartypeoffset[op_previous - OP_CHAR];
+
+ /* Deal with UTF characters that take up more than one code unit. */
+
+#ifdef MAYBE_UTF_MULTI
+ if (utf && NOT_FIRSTCU(code[-1]))
+ {
+ PCRE2_UCHAR *lastchar = code - 1;
+ BACKCHAR(lastchar);
+ mclength = (uint32_t)(code - lastchar); /* Length of UTF character */
+ memcpy(mcbuffer, lastchar, CU2BYTES(mclength)); /* Save the char */
+ }
+ else
+#endif /* MAYBE_UTF_MULTI */
+
+ /* Handle the case of a single code unit - either with no UTF support, or
+ with UTF disabled, or for a single-code-unit UTF character. */
+ {
+ mcbuffer[0] = code[-1];
+ mclength = 1;
+ if (op_previous <= OP_CHARI && repeat_min > 1)
+ {
+ reqcu = mcbuffer[0];
+ reqcuflags = req_caseopt | cb->req_varyopt;
+ }
+ }
+ goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
+
+ /* If previous was a character class or a back reference, we put the
+ repeat stuff after it, but just skip the item if the repeat was {0,0}. */
+
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+#endif
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_REF:
+ case OP_REFI:
+ case OP_DNREF:
+ case OP_DNREFI:
+
+ if (repeat_max == 0)
+ {
+ code = previous;
+ goto END_REPEAT;
+ }
+
+ if (repeat_min == 0 && repeat_max == REPEAT_UNLIMITED)
+ *code++ = OP_CRSTAR + repeat_type;
+ else if (repeat_min == 1 && repeat_max == REPEAT_UNLIMITED)
+ *code++ = OP_CRPLUS + repeat_type;
+ else if (repeat_min == 0 && repeat_max == 1)
+ *code++ = OP_CRQUERY + repeat_type;
+ else
+ {
+ *code++ = OP_CRRANGE + repeat_type;
+ PUT2INC(code, 0, repeat_min);
+ if (repeat_max == REPEAT_UNLIMITED) repeat_max = 0; /* 2-byte encoding for max */
+ PUT2INC(code, 0, repeat_max);
+ }
+ break;
+
+ /* If previous is OP_FAIL, it was generated by an empty class []
+ (PCRE2_ALLOW_EMPTY_CLASS is set). The other ways in which OP_FAIL can be
+ generated, that is by (*FAIL) or (?!), disallow a quantifier at parse
+ time. We can just ignore this repeat. */
+
+ case OP_FAIL:
+ goto END_REPEAT;
+
+ /* If previous was a bracket group, we may have to replicate it in
+ certain cases. Note that at this point we can encounter only the "basic"
+ bracket opcodes such as BRA and CBRA, as this is the place where they get
+ converted into the more special varieties such as BRAPOS and SBRA.
+ Originally, PCRE did not allow repetition of assertions, but now it does,
+ for Perl compatibility. */
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ {
+ int len = (int)(code - previous);
+ PCRE2_UCHAR *bralink = NULL;
+ PCRE2_UCHAR *brazeroptr = NULL;
+
+ /* Repeating a DEFINE group (or any group where the condition is always
+ FALSE and there is only one branch) is pointless, but Perl allows the
+ syntax, so we just ignore the repeat. */
+
+ if (op_previous == OP_COND && previous[LINK_SIZE+1] == OP_FALSE &&
+ previous[GET(previous, 1)] != OP_ALT)
+ goto END_REPEAT;
+
+ /* There is no sense in actually repeating assertions. The only potential
+ use of repetition is in cases when the assertion is optional. Therefore,
+ if the minimum is greater than zero, just ignore the repeat. If the
+ maximum is not zero or one, set it to 1. */
+
+ if (op_previous < OP_ONCE) /* Assertion */
+ {
+ if (repeat_min > 0) goto END_REPEAT;
+ if (repeat_max > 1) repeat_max = 1;
+ }
+
+ /* The case of a zero minimum is special because of the need to stick
+ OP_BRAZERO in front of it, and because the group appears once in the
+ data, whereas in other cases it appears the minimum number of times. For
+ this reason, it is simplest to treat this case separately, as otherwise
+ the code gets far too messy. There are several special subcases when the
+ minimum is zero. */
+
+ if (repeat_min == 0)
+ {
+ /* If the maximum is also zero, we used to just omit the group from
+ the output altogether, like this:
+
+ ** if (repeat_max == 0)
+ ** {
+ ** code = previous;
+ ** goto END_REPEAT;
+ ** }
+
+ However, that fails when a group or a subgroup within it is
+ referenced as a subroutine from elsewhere in the pattern, so now we
+ stick in OP_SKIPZERO in front of it so that it is skipped on
+ execution. As we don't have a list of which groups are referenced, we
+ cannot do this selectively.
+
+ If the maximum is 1 or unlimited, we just have to stick in the
+ BRAZERO and do no more at this point. */
+
+ if (repeat_max <= 1 || repeat_max == REPEAT_UNLIMITED)
+ {
+ memmove(previous + 1, previous, CU2BYTES(len));
+ code++;
+ if (repeat_max == 0)
+ {
+ *previous++ = OP_SKIPZERO;
+ goto END_REPEAT;
+ }
+ brazeroptr = previous; /* Save for possessive optimizing */
+ *previous++ = OP_BRAZERO + repeat_type;
+ }
+
+ /* If the maximum is greater than 1 and limited, we have to replicate
+ in a nested fashion, sticking OP_BRAZERO before each set of brackets.
+ The first one has to be handled carefully because it's the original
+ copy, which has to be moved up. The remainder can be handled by code
+ that is common with the non-zero minimum case below. We have to
+ adjust the value or repeat_max, since one less copy is required. */
+
+ else
+ {
+ int linkoffset;
+ memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len));
+ code += 2 + LINK_SIZE;
+ *previous++ = OP_BRAZERO + repeat_type;
+ *previous++ = OP_BRA;
+
+ /* We chain together the bracket link offset fields that have to be
+ filled in later when the ends of the brackets are reached. */
+
+ linkoffset = (bralink == NULL)? 0 : (int)(previous - bralink);
+ bralink = previous;
+ PUTINC(previous, 0, linkoffset);
+ }
+
+ if (repeat_max != REPEAT_UNLIMITED) repeat_max--;
+ }
+
+ /* If the minimum is greater than zero, replicate the group as many
+ times as necessary, and adjust the maximum to the number of subsequent
+ copies that we need. */
+
+ else
+ {
+ if (repeat_min > 1)
+ {
+ /* In the pre-compile phase, we don't actually do the replication.
+ We just adjust the length as if we had. Do some paranoid checks for
+ potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
+ integer type when available, otherwise double. */
+
+ if (lengthptr != NULL)
+ {
+ PCRE2_SIZE delta = (repeat_min - 1)*length_prevgroup;
+ if ((INT64_OR_DOUBLE)(repeat_min - 1)*
+ (INT64_OR_DOUBLE)length_prevgroup >
+ (INT64_OR_DOUBLE)INT_MAX ||
+ OFLOW_MAX - *lengthptr < delta)
+ {
+ *errorcodeptr = ERR20;
+ return 0;
+ }
+ *lengthptr += delta;
+ }
+
+ /* This is compiling for real. If there is a set first code unit
+ for the group, and we have not yet set a "required code unit", set
+ it. */
+
+ else
+ {
+ if (groupsetfirstcu && reqcuflags < 0)
+ {
+ reqcu = firstcu;
+ reqcuflags = firstcuflags;
+ }
+ for (i = 1; (uint32_t)i < repeat_min; i++)
+ {
+ memcpy(code, previous, CU2BYTES(len));
+ code += len;
+ }
+ }
+ }
+
+ if (repeat_max != REPEAT_UNLIMITED) repeat_max -= repeat_min;
+ }
+
+ /* This code is common to both the zero and non-zero minimum cases. If
+ the maximum is limited, it replicates the group in a nested fashion,
+ remembering the bracket starts on a stack. In the case of a zero
+ minimum, the first one was set up above. In all cases the repeat_max
+ now specifies the number of additional copies needed. Again, we must
+ remember to replicate entries on the forward reference list. */
+
+ if (repeat_max != REPEAT_UNLIMITED)
+ {
+ /* In the pre-compile phase, we don't actually do the replication. We
+ just adjust the length as if we had. For each repetition we must add
+ 1 to the length for BRAZERO and for all but the last repetition we
+ must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
+ paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type
+ is a 64-bit integer type when available, otherwise double. */
+
+ if (lengthptr != NULL && repeat_max > 0)
+ {
+ PCRE2_SIZE delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
+ 2 - 2*LINK_SIZE; /* Last one doesn't nest */
+ if ((INT64_OR_DOUBLE)repeat_max *
+ (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
+ > (INT64_OR_DOUBLE)INT_MAX ||
+ OFLOW_MAX - *lengthptr < delta)
+ {
+ *errorcodeptr = ERR20;
+ return 0;
+ }
+ *lengthptr += delta;
+ }
+
+ /* This is compiling for real */
+
+ else for (i = repeat_max - 1; i >= 0; i--)
+ {
+ *code++ = OP_BRAZERO + repeat_type;
+
+ /* All but the final copy start a new nesting, maintaining the
+ chain of brackets outstanding. */
+
+ if (i != 0)
+ {
+ int linkoffset;
+ *code++ = OP_BRA;
+ linkoffset = (bralink == NULL)? 0 : (int)(code - bralink);
+ bralink = code;
+ PUTINC(code, 0, linkoffset);
+ }
+
+ memcpy(code, previous, CU2BYTES(len));
+ code += len;
+ }
+
+ /* Now chain through the pending brackets, and fill in their length
+ fields (which are holding the chain links pro tem). */
+
+ while (bralink != NULL)
+ {
+ int oldlinkoffset;
+ int linkoffset = (int)(code - bralink + 1);
+ PCRE2_UCHAR *bra = code - linkoffset;
+ oldlinkoffset = GET(bra, 1);
+ bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
+ *code++ = OP_KET;
+ PUTINC(code, 0, linkoffset);
+ PUT(bra, 1, linkoffset);
+ }
+ }
+
+ /* If the maximum is unlimited, set a repeater in the final copy. For
+ ONCE brackets, that's all we need to do. However, possessively repeated
+ ONCE brackets can be converted into non-capturing brackets, as the
+ behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
+ deal with possessive ONCEs specially.
+
+ Otherwise, when we are doing the actual compile phase, check to see
+ whether this group is one that could match an empty string. If so,
+ convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
+ that runtime checking can be done. [This check is also applied to ONCE
+ groups at runtime, but in a different way.]
+
+ Then, if the quantifier was possessive and the bracket is not a
+ conditional, we convert the BRA code to the POS form, and the KET code to
+ KETRPOS. (It turns out to be convenient at runtime to detect this kind of
+ subpattern at both the start and at the end.) The use of special opcodes
+ makes it possible to reduce greatly the stack usage in pcre2_match(). If
+ the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
+
+ Then, if the minimum number of matches is 1 or 0, cancel the possessive
+ flag so that the default action below, of wrapping everything inside
+ atomic brackets, does not happen. When the minimum is greater than 1,
+ there will be earlier copies of the group, and so we still have to wrap
+ the whole thing. */
+
+ else
+ {
+ PCRE2_UCHAR *ketcode = code - 1 - LINK_SIZE;
+ PCRE2_UCHAR *bracode = ketcode - GET(ketcode, 1);
+
+ /* Convert possessive ONCE brackets to non-capturing */
+
+ if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
+ possessive_quantifier) *bracode = OP_BRA;
+
+ /* For non-possessive ONCE brackets, all we need to do is to
+ set the KET. */
+
+ if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
+ *ketcode = OP_KETRMAX + repeat_type;
+
+ /* Handle non-ONCE brackets and possessive ONCEs (which have been
+ converted to non-capturing above). */
+
+ else
+ {
+ /* In the compile phase, adjust the opcode if the group can match
+ an empty string. For a conditional group with only one branch, the
+ value of group_return will not show "could be empty", so we must
+ check that separately. */
+
+ if (lengthptr == NULL)
+ {
+ if (group_return < 0) *bracode += OP_SBRA - OP_BRA;
+ if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)
+ *bracode = OP_SCOND;
+ }
+
+ /* Handle possessive quantifiers. */
+
+ if (possessive_quantifier)
+ {
+ /* For COND brackets, we wrap the whole thing in a possessively
+ repeated non-capturing bracket, because we have not invented POS
+ versions of the COND opcodes. */
+
+ if (*bracode == OP_COND || *bracode == OP_SCOND)
+ {
+ int nlen = (int)(code - bracode);
+ memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));
+ code += 1 + LINK_SIZE;
+ nlen += 1 + LINK_SIZE;
+ *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
+ *code++ = OP_KETRPOS;
+ PUTINC(code, 0, nlen);
+ PUT(bracode, 1, nlen);
+ }
+
+ /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
+
+ else
+ {
+ *bracode += 1; /* Switch to xxxPOS opcodes */
+ *ketcode = OP_KETRPOS;
+ }
+
+ /* If the minimum is zero, mark it as possessive, then unset the
+ possessive flag when the minimum is 0 or 1. */
+
+ if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
+ if (repeat_min < 2) possessive_quantifier = FALSE;
+ }
+
+ /* Non-possessive quantifier */
+
+ else *ketcode = OP_KETRMAX + repeat_type;
+ }
+ }
+ }
+ break;
+
+ /* If previous was a character type match (\d or similar), abolish it and
+ create a suitable repeat item. The code is shared with single-character
+ repeats by setting op_type to add a suitable offset into repeat_type.
+ Note the the Unicode property types will be present only when
+ SUPPORT_UNICODE is defined, but we don't wrap the little bits of code
+ here because it just makes it horribly messy. */
+
+ default:
+ if (op_previous >= OP_EODN) /* Not a character type - internal error */
+ {
+ *errorcodeptr = ERR10;
+ return 0;
+ }
+ else
+ {
+ int prop_type, prop_value;
+ PCRE2_UCHAR *oldcode;
+
+ op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
+ mclength = 0; /* Not a character */
+
+ if (op_previous == OP_PROP || op_previous == OP_NOTPROP)
+ {
+ prop_type = previous[1];
+ prop_value = previous[2];
+ }
+ else
+ {
+ /* Come here from just above with a character in mcbuffer/mclength. */
+ OUTPUT_SINGLE_REPEAT:
+ prop_type = prop_value = -1;
+ }
+
+ /* At this point, if prop_type == prop_value == -1 we either have a
+ character in mcbuffer when mclength is greater than zero, or we have
+ mclength zero, in which case there is a non-property character type in
+ op_previous. If prop_type/value are not negative, we have a property
+ character type in op_previous. */
+
+ oldcode = code; /* Save where we were */
+ code = previous; /* Usually overwrite previous item */
+
+ /* If the maximum is zero then the minimum must also be zero; Perl allows
+ this case, so we do too - by simply omitting the item altogether. */
+
+ if (repeat_max == 0) goto END_REPEAT;
+
+ /* Combine the op_type with the repeat_type */
+
+ repeat_type += op_type;
+
+ /* A minimum of zero is handled either as the special case * or ?, or as
+ an UPTO, with the maximum given. */
+
+ if (repeat_min == 0)
+ {
+ if (repeat_max == REPEAT_UNLIMITED) *code++ = OP_STAR + repeat_type;
+ else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
+ else
+ {
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+
+ /* A repeat minimum of 1 is optimized into some special cases. If the
+ maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
+ left in place and, if the maximum is greater than 1, we use OP_UPTO with
+ one less than the maximum. */
+
+ else if (repeat_min == 1)
+ {
+ if (repeat_max == REPEAT_UNLIMITED)
+ *code++ = OP_PLUS + repeat_type;
+ else
+ {
+ code = oldcode; /* Leave previous item in place */
+ if (repeat_max == 1) goto END_REPEAT;
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max - 1);
+ }
+ }
+
+ /* The case {n,n} is just an EXACT, while the general case {n,m} is
+ handled as an EXACT followed by an UPTO or STAR or QUERY. */
+
+ else
+ {
+ *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */
+ PUT2INC(code, 0, repeat_min);
+
+ /* Unless repeat_max equals repeat_min, fill in the data for EXACT,
+ and then generate the second opcode. For a repeated Unicode property
+ match, there are two extra values that define the required property,
+ and mclength is set zero to indicate this. */
+
+ if (repeat_max != repeat_min)
+ {
+ if (mclength > 0)
+ {
+ memcpy(code, mcbuffer, CU2BYTES(mclength));
+ code += mclength;
+ }
+ else
+ {
+ *code++ = op_previous;
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+ }
+
+ /* Now set up the following opcode */
+
+ if (repeat_max == REPEAT_UNLIMITED)
+ *code++ = OP_STAR + repeat_type;
+ else
+ {
+ repeat_max -= repeat_min;
+ if (repeat_max == 1)
+ {
+ *code++ = OP_QUERY + repeat_type;
+ }
+ else
+ {
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+ }
+ }
+
+ /* Fill in the character or character type for the final opcode. */
+
+ if (mclength > 0)
+ {
+ memcpy(code, mcbuffer, CU2BYTES(mclength));
+ code += mclength;
+ }
+ else
+ {
+ *code++ = op_previous;
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+ }
+ }
+ break;
+ } /* End of switch on different op_previous values */
+
+
+ /* If the character following a repeat is '+', possessive_quantifier is
+ TRUE. For some opcodes, there are special alternative opcodes for this
+ case. For anything else, we wrap the entire repeated item inside OP_ONCE
+ brackets. Logically, the '+' notation is just syntactic sugar, taken from
+ Sun's Java package, but the special opcodes can optimize it.
+
+ Some (but not all) possessively repeated subpatterns have already been
+ completely handled in the code just above. For them, possessive_quantifier
+ is always FALSE at this stage. Note that the repeated item starts at
+ tempcode, not at previous, which might be the first part of a string whose
+ (former) last char we repeated. */
+
+ if (possessive_quantifier)
+ {
+ int len;
+
+ /* Possessifying an EXACT quantifier has no effect, so we can ignore it.
+ However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6},
+ {5,}, or {5,10}). We skip over an EXACT item; if the length of what
+ remains is greater than zero, there's a further opcode that can be
+ handled. If not, do nothing, leaving the EXACT alone. */
+
+ switch(*tempcode)
+ {
+ case OP_TYPEEXACT:
+ tempcode += PRIV(OP_lengths)[*tempcode] +
+ ((tempcode[1 + IMM2_SIZE] == OP_PROP
+ || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+ break;
+
+ /* CHAR opcodes are used for exacts whose count is 1. */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ tempcode += PRIV(OP_lengths)[*tempcode];
+#ifdef SUPPORT_UNICODE
+ if (utf && HAS_EXTRALEN(tempcode[-1]))
+ tempcode += GET_EXTRALEN(tempcode[-1]);
+#endif
+ break;
+
+ /* For the class opcodes, the repeat operator appears at the end;
+ adjust tempcode to point to it. */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ tempcode += 1 + 32/sizeof(PCRE2_UCHAR);
+ break;
+
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ tempcode += GET(tempcode, 1);
+ break;
+#endif
+ }
+
+ /* If tempcode is equal to code (which points to the end of the repeated
+ item), it means we have skipped an EXACT item but there is no following
+ QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In
+ all other cases, tempcode will be pointing to the repeat opcode, and will
+ be less than code, so the value of len will be greater than 0. */
+
+ len = (int)(code - tempcode);
+ if (len > 0)
+ {
+ unsigned int repcode = *tempcode;
+
+ /* There is a table for possessifying opcodes, all of which are less
+ than OP_CALLOUT. A zero entry means there is no possessified version.
+ */
+
+ if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0)
+ *tempcode = opcode_possessify[repcode];
+
+ /* For opcode without a special possessified version, wrap the item in
+ ONCE brackets. */
+
+ else
+ {
+ memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len));
+ code += 1 + LINK_SIZE;
+ len += 1 + LINK_SIZE;
+ tempcode[0] = OP_ONCE;
+ *code++ = OP_KET;
+ PUTINC(code, 0, len);
+ PUT(tempcode, 1, len);
+ }
+ }
+ }
+
+ /* We set the "follows varying string" flag for subsequently encountered
+ reqcus if it isn't already set and we have just passed a varying length
+ item. */
+
+ END_REPEAT:
+ cb->req_varyopt |= reqvary;
+ break;
+
+
+ /* ===================================================================*/
+ /* Handle a 32-bit data character with a value greater than META_END. */
+
+ case META_BIGVALUE:
+ pptr++;
+ goto NORMAL_CHAR;
+
+
+ /* ===============================================================*/
+ /* Handle a back reference by number, which is the meta argument. The
+ pattern offsets for back references to group numbers less than 10 are held
+ in a special vector, to avoid using more than two parsed pattern elements
+ in 64-bit environments. We only need the offset to the first occurrence,
+ because if that doesn't fail, subsequent ones will also be OK. */
+
+ case META_BACKREF:
+ if (meta_arg < 10) offset = cb->small_ref_offset[meta_arg];
+ else GETPLUSOFFSET(offset, pptr);
+
+ if (meta_arg > cb->bracount)
+ {
+ cb->erroroffset = offset;
+ *errorcodeptr = ERR15; /* Non-existent subpattern */
+ return 0;
+ }
+
+ /* Come here from named backref handling when the reference is to a
+ single group (that is, not to a duplicated name). The back reference
+ data will have already been updated. We must disable firstcu if not
+ set, to cope with cases like (?=(\w+))\1: which would otherwise set ':'
+ later. */
+
+ HANDLE_SINGLE_REFERENCE:
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;
+ PUT2INC(code, 0, meta_arg);
+
+ /* Update the map of back references, and keep the highest one. We
+ could do this in parse_regex() for numerical back references, but not
+ for named back references, because we don't know the numbers to which
+ named back references refer. So we do it all in this function. */
+
+ cb->backref_map |= (meta_arg < 32)? (1u << meta_arg) : 1;
+ if (meta_arg > cb->top_backref) cb->top_backref = meta_arg;
+
+ /* Check to see if this back reference is recursive, that it, it
+ is inside the group that it references. A flag is set so that the
+ group can be made atomic. */
+
+ for (oc = cb->open_caps; oc != NULL; oc = oc->next)
+ {
+ if (oc->number == meta_arg)
+ {
+ oc->flag = TRUE;
+ break;
+ }
+ }
+ break;
+
+
+ /* ===============================================================*/
+ /* Handle recursion by inserting the number of the called group (which is
+ the meta argument) after OP_RECURSE. At the end of compiling the pattern is
+ scanned and these numbers are replaced by offsets within the pattern. It is
+ done like this to avoid problems with forward references and adjusting
+ offsets when groups are duplicated and moved (as discovered in previous
+ implementations). Note that a recursion does not have a set first character
+ (relevant if it is repeated, because it will then be wrapped with ONCE
+ brackets). */
+
+ case META_RECURSE:
+ GETPLUSOFFSET(offset, pptr);
+ if (meta_arg > cb->bracount)
+ {
+ cb->erroroffset = offset;
+ *errorcodeptr = ERR15; /* Non-existent subpattern */
+ return 0;
+ }
+ HANDLE_NUMERICAL_RECURSION:
+ *code = OP_RECURSE;
+ PUT(code, 1, meta_arg);
+ code += 1 + LINK_SIZE;
+ groupsetfirstcu = FALSE;
+ cb->had_recurse = TRUE;
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ break;
+
+
+ /* ===============================================================*/
+ /* Handle capturing parentheses; the number is the meta argument. */
+
+ case META_CAPTURE:
+ bravalue = OP_CBRA;
+ skipunits = IMM2_SIZE;
+ PUT2(code, 1+LINK_SIZE, meta_arg);
+ cb->lastcapture = meta_arg;
+ goto GROUP_PROCESS_NOTE_EMPTY;
+
+
+ /* ===============================================================*/
+ /* Handle escape sequence items. For ones like \d, the ESC_values are
+ arranged to be the same as the corresponding OP_values in the default case
+ when PCRE2_UCP is not set (which is the only case in which they will appear
+ here).
+
+ Note: \Q and \E are never seen here, as they were dealt with in
+ parse_pattern(). Neither are numerical back references or recursions, which
+ were turned into META_BACKREF or META_RECURSE items, respectively. \k and
+ \g, when followed by names, are turned into META_BACKREF_BYNAME or
+ META_RECURSE_BYNAME. */
+
+ case META_ESCAPE:
+
+ /* We can test for escape sequences that consume a character because their
+ values lie between ESC_b and ESC_Z; this may have to change if any new ones
+ are ever created. For these sequences, we disable the setting of a first
+ character if it hasn't already been set. */
+
+ if (meta_arg > ESC_b && meta_arg < ESC_Z)
+ {
+ matched_char = TRUE;
+ if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+ }
+
+ /* Set values to reset to if this is followed by a zero repeat. */
+
+ zerofirstcu = firstcu;
+ zerofirstcuflags = firstcuflags;
+ zeroreqcu = reqcu;
+ zeroreqcuflags = reqcuflags;
+
+ /* If Unicode is not supported, \P and \p are not allowed and are
+ faulted at parse time, so will never appear here. */
+
+#ifdef SUPPORT_UNICODE
+ if (meta_arg == ESC_P || meta_arg == ESC_p)
+ {
+ uint32_t ptype = *(++pptr) >> 16;
+ uint32_t pdata = *pptr & 0xffff;
+ *code++ = (meta_arg == ESC_p)? OP_PROP : OP_NOTPROP;
+ *code++ = ptype;
+ *code++ = pdata;
+ break; /* End META_ESCAPE */
+ }
+#endif
+
+ /* For the rest (including \X when Unicode is supported - if not it's
+ faulted at parse time), the OP value is the escape value when PCRE2_UCP is
+ not set; if it is set, these escapes do not show up here because they are
+ converted into Unicode property tests in parse_regex(). Note that \b and \B
+ do a one-character lookbehind, and \A also behaves as if it does. */
+
+ if (meta_arg == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */
+ if ((meta_arg == ESC_b || meta_arg == ESC_B || meta_arg == ESC_A) &&
+ cb->max_lookbehind == 0)
+ cb->max_lookbehind = 1;
+
+ /* In non-UTF mode, and for both 32-bit modes, we turn \C into OP_ALLANY
+ instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 32
+ *code++ = (meta_arg == ESC_C)? OP_ALLANY : meta_arg;
+#else
+ *code++ = (!utf && meta_arg == ESC_C)? OP_ALLANY : meta_arg;
+#endif
+ break; /* End META_ESCAPE */
+
+
+ /* ===================================================================*/
+ /* Handle an unrecognized meta value. A parsed pattern value less than
+ META_END is a literal. Otherwise we have a problem. */
+
+ default:
+ if (meta >= META_END)
+ {
+#ifdef DEBUG_SHOW_PARSED
+ fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x\n", *pptr);
+#endif
+ *errorcodeptr = ERR89; /* Internal error - unrecognized. */
+ return 0;
+ }
+
+ /* Handle a literal character. We come here by goto in the case of a
+ 32-bit, non-UTF character whose value is greater than META_END. */
+
+ NORMAL_CHAR:
+ meta = *pptr; /* Get the full 32 bits */
+ NORMAL_CHAR_SET: /* Character is already in meta */
+ matched_char = TRUE;
+
+ /* For caseless UTF mode, check whether this character has more than one
+ other case. If so, generate a special OP_PROP item instead of OP_CHARI. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf && (options & PCRE2_CASELESS) != 0)
+ {
+ uint32_t caseset = UCD_CASESET(meta);
+ if (caseset != 0)
+ {
+ *code++ = OP_PROP;
+ *code++ = PT_CLIST;
+ *code++ = caseset;
+ if (firstcuflags == REQ_UNSET)
+ firstcuflags = zerofirstcuflags = REQ_NONE;
+ break; /* End handling this meta item */
+ }
+ }
+#endif
+
+ /* Caseful matches, or not one of the multicase characters. Get the
+ character's code units into mcbuffer, with the length in mclength. When not
+ in UTF mode, the length is always 1. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else
+#endif
+ {
+ mclength = 1;
+ mcbuffer[0] = meta;
+ }
+
+ /* Generate the appropriate code */
+
+ *code++ = ((options & PCRE2_CASELESS) != 0)? OP_CHARI : OP_CHAR;
+ memcpy(code, mcbuffer, CU2BYTES(mclength));
+ code += mclength;
+
+ /* Remember if \r or \n were seen */
+
+ if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
+ cb->external_flags |= PCRE2_HASCRORLF;
+
+ /* Set the first and required code units appropriately. If no previous
+ first code unit, set it from this character, but revert to none on a zero
+ repeat. Otherwise, leave the firstcu value alone, and don't change it on
+ a zero repeat. */
+
+ if (firstcuflags == REQ_UNSET)
+ {
+ zerofirstcuflags = REQ_NONE;
+ zeroreqcu = reqcu;
+ zeroreqcuflags = reqcuflags;
+
+ /* If the character is more than one code unit long, we can set firstcu
+ only if it is not to be matched caselessly. */
+
+ if (mclength == 1 || req_caseopt == 0)
+ {
+ firstcu = mcbuffer[0] | req_caseopt;
+ firstcu = mcbuffer[0];
+ firstcuflags = req_caseopt;
+ if (mclength != 1)
+ {
+ reqcu = code[-1];
+ reqcuflags = cb->req_varyopt;
+ }
+ }
+ else firstcuflags = reqcuflags = REQ_NONE;
+ }
+
+ /* firstcu was previously set; we can set reqcu only if the length is
+ 1 or the matching is caseful. */
+
+ else
+ {
+ zerofirstcu = firstcu;
+ zerofirstcuflags = firstcuflags;
+ zeroreqcu = reqcu;
+ zeroreqcuflags = reqcuflags;
+ if (mclength == 1 || req_caseopt == 0)
+ {
+ reqcu = code[-1];
+ reqcuflags = req_caseopt | cb->req_varyopt;
+ }
+ }
+ break; /* End default meta handling */
+ } /* End of big switch */
+ } /* End of big loop */
+
+/* Control never reaches here. */
+}
+
+
+
+/*************************************************
+* Compile regex: a sequence of alternatives *
+*************************************************/
+
+/* On entry, pptr is pointing past the bracket meta, but on return it points to
+the closing bracket or META_END. The code variable is pointing at the code unit
+into which the BRA operator has been stored. This function is used during the
+pre-compile phase when we are trying to find out the amount of memory needed,
+as well as during the real compile phase. The value of lengthptr distinguishes
+the two phases.
+
+Arguments:
+ options option bits, including any changes for this subpattern
+ codeptr -> the address of the current code pointer
+ pptrptr -> the address of the current parsed pattern pointer
+ errorcodeptr -> pointer to error code variable
+ skipunits skip this many code units at start (for brackets and OP_COND)
+ firstcuptr place to put the first required code unit
+ firstcuflagsptr place to put the first code unit flags, or a negative number
+ reqcuptr place to put the last required code unit
+ reqcuflagsptr place to put the last required code unit flags, or a negative number
+ bcptr pointer to the chain of currently open branches
+ cb points to the data block with tables pointers etc.
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: 0 There has been an error
+ +1 Success, this group must match at least one character
+ -1 Success, this group may match an empty string
+*/
+
+static int
+compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, uint32_t **pptrptr,
+ int *errorcodeptr, uint32_t skipunits, uint32_t *firstcuptr,
+ int32_t *firstcuflagsptr, uint32_t *reqcuptr,int32_t *reqcuflagsptr,
+ branch_chain *bcptr, compile_block *cb, PCRE2_SIZE *lengthptr)
+{
+PCRE2_UCHAR *code = *codeptr;
+PCRE2_UCHAR *last_branch = code;
+PCRE2_UCHAR *start_bracket = code;
+BOOL lookbehind;
+open_capitem capitem;
+int capnumber = 0;
+int okreturn = 1;
+uint32_t *pptr = *pptrptr;
+uint32_t firstcu, reqcu;
+uint32_t lookbehindlength;
+int32_t firstcuflags, reqcuflags;
+uint32_t branchfirstcu, branchreqcu;
+int32_t branchfirstcuflags, branchreqcuflags;
+PCRE2_SIZE length;
+branch_chain bc;
+
+/* If set, call the external function that checks for stack availability. */
+
+if (cb->cx->stack_guard != NULL &&
+ cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data))
+ {
+ *errorcodeptr= ERR33;
+ return 0;
+ }
+
+/* Miscellaneous initialization */
+
+bc.outer = bcptr;
+bc.current_branch = code;
+
+firstcu = reqcu = 0;
+firstcuflags = reqcuflags = REQ_UNSET;
+
+/* Accumulate the length for use in the pre-compile phase. Start with the
+length of the BRA and KET and any extra code units that are required at the
+beginning. We accumulate in a local variable to save frequent testing of
+lengthptr for NULL. We cannot do this by looking at the value of 'code' at the
+start and end of each alternative, because compiled items are discarded during
+the pre-compile phase so that the work space is not exceeded. */
+
+length = 2 + 2*LINK_SIZE + skipunits;
+
+/* Remember if this is a lookbehind assertion, and if it is, save its length
+and skip over the pattern offset. */
+
+lookbehind = *code == OP_ASSERTBACK || *code == OP_ASSERTBACK_NOT;
+if (lookbehind)
+ {
+ lookbehindlength = META_DATA(pptr[-1]);
+ pptr += SIZEOFFSET;
+ }
+else lookbehindlength = 0;
+
+/* If this is a capturing subpattern, add to the chain of open capturing items
+so that we can detect them if (*ACCEPT) is encountered. Note that only OP_CBRA
+need be tested here; changing this opcode to one of its variants, e.g.
+OP_SCBRAPOS, happens later, after the group has been compiled. */
+
+if (*code == OP_CBRA)
+ {
+ capnumber = GET2(code, 1 + LINK_SIZE);
+ capitem.number = capnumber;
+ capitem.next = cb->open_caps;
+ capitem.flag = FALSE;
+ cb->open_caps = &capitem;
+ }
+
+/* Offset is set zero to mark that this bracket is still open */
+
+PUT(code, 1, 0);
+code += 1 + LINK_SIZE + skipunits;
+
+/* Loop for each alternative branch */
+
+for (;;)
+ {
+ int branch_return;
+
+ /* Insert OP_REVERSE if this is as lookbehind assertion. */
+
+ if (lookbehind && lookbehindlength > 0)
+ {
+ *code++ = OP_REVERSE;
+ PUTINC(code, 0, lookbehindlength);
+ length += 1 + LINK_SIZE;
+ }
+
+ /* Now compile the branch; in the pre-compile phase its length gets added
+ into the length. */
+
+ if ((branch_return =
+ compile_branch(&options, &code, &pptr, errorcodeptr, &branchfirstcu,
+ &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc,
+ cb, (lengthptr == NULL)? NULL : &length)) == 0)
+ return 0;
+
+ /* If a branch can match an empty string, so can the whole group. */
+
+ if (branch_return < 0) okreturn = -1;
+
+ /* In the real compile phase, there is some post-processing to be done. */
+
+ if (lengthptr == NULL)
+ {
+ /* If this is the first branch, the firstcu and reqcu values for the
+ branch become the values for the regex. */
+
+ if (*last_branch != OP_ALT)
+ {
+ firstcu = branchfirstcu;
+ firstcuflags = branchfirstcuflags;
+ reqcu = branchreqcu;
+ reqcuflags = branchreqcuflags;
+ }
+
+ /* If this is not the first branch, the first char and reqcu have to
+ match the values from all the previous branches, except that if the
+ previous value for reqcu didn't have REQ_VARY set, it can still match,
+ and we set REQ_VARY for the regex. */
+
+ else
+ {
+ /* If we previously had a firstcu, but it doesn't match the new branch,
+ we have to abandon the firstcu for the regex, but if there was
+ previously no reqcu, it takes on the value of the old firstcu. */
+
+ if (firstcuflags != branchfirstcuflags || firstcu != branchfirstcu)
+ {
+ if (firstcuflags >= 0)
+ {
+ if (reqcuflags < 0)
+ {
+ reqcu = firstcu;
+ reqcuflags = firstcuflags;
+ }
+ }
+ firstcuflags = REQ_NONE;
+ }
+
+ /* If we (now or from before) have no firstcu, a firstcu from the
+ branch becomes a reqcu if there isn't a branch reqcu. */
+
+ if (firstcuflags < 0 && branchfirstcuflags >= 0 &&
+ branchreqcuflags < 0)
+ {
+ branchreqcu = branchfirstcu;
+ branchreqcuflags = branchfirstcuflags;
+ }
+
+ /* Now ensure that the reqcus match */
+
+ if (((reqcuflags & ~REQ_VARY) != (branchreqcuflags & ~REQ_VARY)) ||
+ reqcu != branchreqcu)
+ reqcuflags = REQ_NONE;
+ else
+ {
+ reqcu = branchreqcu;
+ reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY */
+ }
+ }
+ }
+
+ /* Handle reaching the end of the expression, either ')' or end of pattern.
+ In the real compile phase, go back through the alternative branches and
+ reverse the chain of offsets, with the field in the BRA item now becoming an
+ offset to the first alternative. If there are no alternatives, it points to
+ the end of the group. The length in the terminating ket is always the length
+ of the whole bracketed item. Return leaving the pointer at the terminating
+ char. */
+
+ if (META_CODE(*pptr) != META_ALT)
+ {
+ if (lengthptr == NULL)
+ {
+ PCRE2_SIZE branch_length = code - last_branch;
+ do
+ {
+ PCRE2_SIZE prev_length = GET(last_branch, 1);
+ PUT(last_branch, 1, branch_length);
+ branch_length = prev_length;
+ last_branch -= branch_length;
+ }
+ while (branch_length > 0);
+ }
+
+ /* Fill in the ket */
+
+ *code = OP_KET;
+ PUT(code, 1, (int)(code - start_bracket));
+ code += 1 + LINK_SIZE;
+
+ /* If it was a capturing subpattern, check to see if it contained any
+ recursive back references. If so, we must wrap it in atomic brackets. In
+ any event, remove the block from the chain. */
+
+ if (capnumber > 0)
+ {
+ if (cb->open_caps->flag)
+ {
+ memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+ CU2BYTES(code - start_bracket));
+ *start_bracket = OP_ONCE;
+ code += 1 + LINK_SIZE;
+ PUT(start_bracket, 1, (int)(code - start_bracket));
+ *code = OP_KET;
+ PUT(code, 1, (int)(code - start_bracket));
+ code += 1 + LINK_SIZE;
+ length += 2 + 2*LINK_SIZE;
+ }
+ cb->open_caps = cb->open_caps->next;
+ }
+
+ /* Set values to pass back */
+
+ *codeptr = code;
+ *pptrptr = pptr;
+ *firstcuptr = firstcu;
+ *firstcuflagsptr = firstcuflags;
+ *reqcuptr = reqcu;
+ *reqcuflagsptr = reqcuflags;
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < length)
+ {
+ *errorcodeptr = ERR20;
+ return 0;
+ }
+ *lengthptr += length;
+ }
+ return okreturn;
+ }
+
+ /* Another branch follows. In the pre-compile phase, we can move the code
+ pointer back to where it was for the start of the first branch. (That is,
+ pretend that each branch is the only one.)
+
+ In the real compile phase, insert an ALT node. Its length field points back
+ to the previous branch while the bracket remains open. At the end the chain
+ is reversed. It's done like this so that the start of the bracket has a
+ zero offset until it is closed, making it possible to detect recursion. */
+
+ if (lengthptr != NULL)
+ {
+ code = *codeptr + 1 + LINK_SIZE + skipunits;
+ length += 1 + LINK_SIZE;
+ }
+ else
+ {
+ *code = OP_ALT;
+ PUT(code, 1, (int)(code - last_branch));
+ bc.current_branch = last_branch = code;
+ code += 1 + LINK_SIZE;
+ }
+
+ /* Set the lookbehind length (if not in a lookbehind the value will be zero)
+ and then advance past the vertical bar. */
+
+ lookbehindlength = META_DATA(*pptr);
+ pptr++;
+ }
+/* Control never reaches here */
+}
+
+
+
+/*************************************************
+* Check for anchored pattern *
+*************************************************/
+
+/* Try to find out if this is an anchored regular expression. Consider each
+alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
+all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
+it's anchored. However, if this is a multiline pattern, then only OP_SOD will
+be found, because ^ generates OP_CIRCM in that mode.
+
+We can also consider a regex to be anchored if OP_SOM starts all its branches.
+This is the code for \G, which means "match at start of match position, taking
+into account the match offset".
+
+A branch is also implicitly anchored if it starts with .* and DOTALL is set,
+because that will try the rest of the pattern at all possible matching points,
+so there is no point trying again.... er ....
+
+.... except when the .* appears inside capturing parentheses, and there is a
+subsequent back reference to those parentheses. We haven't enough information
+to catch that case precisely.
+
+At first, the best we could do was to detect when .* was in capturing brackets
+and the highest back reference was greater than or equal to that level.
+However, by keeping a bitmap of the first 31 back references, we can catch some
+of the more common cases more precisely.
+
+... A second exception is when the .* appears inside an atomic group, because
+this prevents the number of characters it matches from being adjusted.
+
+Arguments:
+ code points to start of the compiled pattern
+ bracket_map a bitmap of which brackets we are inside while testing; this
+ handles up to substring 31; after that we just have to take
+ the less precise approach
+ cb points to the compile data block
+ atomcount atomic group level
+ inassert TRUE if in an assertion
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_anchored(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb,
+ int atomcount, BOOL inassert)
+{
+do {
+ PCRE2_SPTR scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
+ int op = *scode;
+
+ /* Non-capturing brackets */
+
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
+ {
+ if (!is_anchored(scode, bracket_map, cb, atomcount, inassert))
+ return FALSE;
+ }
+
+ /* Capturing brackets */
+
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
+ {
+ int n = GET2(scode, 1+LINK_SIZE);
+ int new_map = bracket_map | ((n < 32)? (1u << n) : 1);
+ if (!is_anchored(scode, new_map, cb, atomcount, inassert)) return FALSE;
+ }
+
+ /* Positive forward assertion */
+
+ else if (op == OP_ASSERT)
+ {
+ if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;
+ }
+
+ /* Condition */
+
+ else if (op == OP_COND)
+ {
+ if (!is_anchored(scode, bracket_map, cb, atomcount, inassert))
+ return FALSE;
+ }
+
+ /* Atomic groups */
+
+ else if (op == OP_ONCE || op == OP_ONCE_NC)
+ {
+ if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert))
+ return FALSE;
+ }
+
+ /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
+ it isn't in brackets that are or may be referenced or inside an atomic
+ group or an assertion. Also the pattern must not contain *PRUNE or *SKIP,
+ because these break the feature. Consider, for example, /(?s).*?(*PRUNE)b/
+ with the subject "aab", which matches "b", i.e. not at the start of a line.
+ There is also an option that disables auto-anchoring. */
+
+ else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
+ op == OP_TYPEPOSSTAR))
+ {
+ if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 ||
+ atomcount > 0 || cb->had_pruneorskip || inassert ||
+ (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)
+ return FALSE;
+ }
+
+ /* Check for explicit anchoring */
+
+ else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
+
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT); /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check for starting with ^ or .* *
+*************************************************/
+
+/* This is called to find out if every branch starts with ^ or .* so that
+"first char" processing can be done to speed things up in multiline
+matching and for non-DOTALL patterns that start with .* (which must start at
+the beginning or after \n). As in the case of is_anchored() (see above), we
+have to take account of back references to capturing brackets that contain .*
+because in that case we can't make the assumption. Also, the appearance of .*
+inside atomic brackets or in an assertion, or in a pattern that contains *PRUNE
+or *SKIP does not count, because once again the assumption no longer holds.
+
+Arguments:
+ code points to start of the compiled pattern or a group
+ bracket_map a bitmap of which brackets we are inside while testing; this
+ handles up to substring 31; after that we just have to take
+ the less precise approach
+ cb points to the compile data
+ atomcount atomic group level
+ inassert TRUE if in an assertion
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb,
+ int atomcount, BOOL inassert)
+{
+do {
+ PCRE2_SPTR scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
+ int op = *scode;
+
+ /* If we are at the start of a conditional assertion group, *both* the
+ conditional assertion *and* what follows the condition must satisfy the test
+ for start of line. Other kinds of condition fail. Note that there may be an
+ auto-callout at the start of a condition. */
+
+ if (op == OP_COND)
+ {
+ scode += 1 + LINK_SIZE;
+
+ if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
+ else if (*scode == OP_CALLOUT_STR) scode += GET(scode, 1 + 2*LINK_SIZE);
+
+ switch (*scode)
+ {
+ case OP_CREF:
+ case OP_DNCREF:
+ case OP_RREF:
+ case OP_DNRREF:
+ case OP_FAIL:
+ case OP_FALSE:
+ case OP_TRUE:
+ return FALSE;
+
+ default: /* Assertion */
+ if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;
+ do scode += GET(scode, 1); while (*scode == OP_ALT);
+ scode += 1 + LINK_SIZE;
+ break;
+ }
+ scode = first_significant_code(scode, FALSE);
+ op = *scode;
+ }
+
+ /* Non-capturing brackets */
+
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
+ {
+ if (!is_startline(scode, bracket_map, cb, atomcount, inassert))
+ return FALSE;
+ }
+
+ /* Capturing brackets */
+
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
+ {
+ int n = GET2(scode, 1+LINK_SIZE);
+ int new_map = bracket_map | ((n < 32)? (1u << n) : 1);
+ if (!is_startline(scode, new_map, cb, atomcount, inassert)) return FALSE;
+ }
+
+ /* Positive forward assertions */
+
+ else if (op == OP_ASSERT)
+ {
+ if (!is_startline(scode, bracket_map, cb, atomcount, TRUE))
+ return FALSE;
+ }
+
+ /* Atomic brackets */
+
+ else if (op == OP_ONCE || op == OP_ONCE_NC)
+ {
+ if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert))
+ return FALSE;
+ }
+
+ /* .* means "start at start or after \n" if it isn't in atomic brackets or
+ brackets that may be referenced or an assertion, and as long as the pattern
+ does not contain *PRUNE or *SKIP, because these break the feature. Consider,
+ for example, /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab",
+ i.e. not at the start of a line. There is also an option that disables this
+ optimization. */
+
+ else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
+ {
+ if (scode[1] != OP_ANY || (bracket_map & cb->backref_map) != 0 ||
+ atomcount > 0 || cb->had_pruneorskip || inassert ||
+ (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)
+ return FALSE;
+ }
+
+ /* Check for explicit circumflex; anything else gives a FALSE result. Note
+ in particular that this includes atomic brackets OP_ONCE and OP_ONCE_NC
+ because the number of characters matched by .* cannot be adjusted inside
+ them. */
+
+ else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
+
+ /* Move on to the next alternative */
+
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT); /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+* Scan compiled regex for recursion reference *
+*************************************************/
+
+/* This function scans through a compiled pattern until it finds an instance of
+OP_RECURSE.
+
+Arguments:
+ code points to start of expression
+ utf TRUE in UTF mode
+
+Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
+*/
+
+static PCRE2_SPTR
+find_recurse(PCRE2_SPTR code, BOOL utf)
+{
+for (;;)
+ {
+ PCRE2_UCHAR c = *code;
+ if (c == OP_END) return NULL;
+ if (c == OP_RECURSE) return code;
+
+ /* XCLASS is used for classes that cannot be represented just by a bit map.
+ This includes negated single high-valued characters. CALLOUT_STR is used for
+ callouts with string arguments. In both cases the length in the table is
+ zero; the actual length is stored in the compiled code. */
+
+ if (c == OP_XCLASS) code += GET(code, 1);
+ else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);
+
+ /* Otherwise, we can get the item's length from the table, except that for
+ repeated character types, we have to test for \p and \P, which have an extra
+ two code units of parameters, and for MARK/PRUNE/SKIP/THEN with an argument,
+ we must add in its length. */
+
+ else
+ {
+ switch(c)
+ {
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEPOSUPTO:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
+ code += 2;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ code += PRIV(OP_lengths)[c];
+
+ /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may
+ be followed by a multi-unit character. The length in the table is a
+ minimum, so we have to arrange to skip the extra units. */
+
+#ifdef MAYBE_UTF_MULTI
+ if (utf) switch(c)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif /* MAYBE_UTF_MULTI */
+ }
+ }
+}
+
+
+
+/*************************************************
+* Check for asserted fixed first code unit *
+*************************************************/
+
+/* During compilation, the "first code unit" settings from forward assertions
+are discarded, because they can cause conflicts with actual literals that
+follow. However, if we end up without a first code unit setting for an
+unanchored pattern, it is worth scanning the regex to see if there is an
+initial asserted first code unit. If all branches start with the same asserted
+code unit, or with a non-conditional bracket all of whose alternatives start
+with the same asserted code unit (recurse ad lib), then we return that code
+unit, with the flags set to zero or REQ_CASELESS; otherwise return zero with
+REQ_NONE in the flags.
+
+Arguments:
+ code points to start of compiled pattern
+ flags points to the first code unit flags
+ inassert TRUE if in an assertion
+
+Returns: the fixed first code unit, or 0 with REQ_NONE in flags
+*/
+
+static uint32_t
+find_firstassertedcu(PCRE2_SPTR code, int32_t *flags, BOOL inassert)
+{
+uint32_t c = 0;
+int cflags = REQ_NONE;
+
+*flags = REQ_NONE;
+do {
+ uint32_t d;
+ int dflags;
+ int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
+ PCRE2_SPTR scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE);
+ PCRE2_UCHAR op = *scode;
+
+ switch(op)
+ {
+ default:
+ return 0;
+
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_ASSERT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ d = find_firstassertedcu(scode, &dflags, op == OP_ASSERT);
+ if (dflags < 0)
+ return 0;
+ if (cflags < 0) { c = d; cflags = dflags; }
+ else if (c != d || cflags != dflags) return 0;
+ break;
+
+ case OP_EXACT:
+ scode += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_CHAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ if (!inassert) return 0;
+ if (cflags < 0) { c = scode[1]; cflags = 0; }
+ else if (c != scode[1]) return 0;
+ break;
+
+ case OP_EXACTI:
+ scode += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ if (!inassert) return 0;
+ if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; }
+ else if (c != scode[1]) return 0;
+ break;
+ }
+
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT);
+
+*flags = cflags;
+return c;
+}
+
+
+
+/*************************************************
+* Add an entry to the name/number table *
+*************************************************/
+
+/* This function is called between compiling passes to add an entry to the
+name/number table, maintaining alphabetical order. Checking for permitted
+and forbidden duplicates has already been done.
+
+Arguments:
+ cb the compile data block
+ name the name to add
+ length the length of the name
+ groupno the group number
+ tablecount the count of names in the table so far
+
+Returns: nothing
+*/
+
+static void
+add_name_to_table(compile_block *cb, PCRE2_SPTR name, int length,
+ unsigned int groupno, uint32_t tablecount)
+{
+uint32_t i;
+PCRE2_UCHAR *slot = cb->name_table;
+
+for (i = 0; i < tablecount; i++)
+ {
+ int crc = memcmp(name, slot+IMM2_SIZE, CU2BYTES(length));
+ if (crc == 0 && slot[IMM2_SIZE+length] != 0)
+ crc = -1; /* Current name is a substring */
+
+ /* Make space in the table and break the loop for an earlier name. For a
+ duplicate or later name, carry on. We do this for duplicates so that in the
+ simple case (when ?(| is not used) they are in order of their numbers. In all
+ cases they are in the order in which they appear in the pattern. */
+
+ if (crc < 0)
+ {
+ memmove(slot + cb->name_entry_size, slot,
+ CU2BYTES((tablecount - i) * cb->name_entry_size));
+ break;
+ }
+
+ /* Continue the loop for a later or duplicate name */
+
+ slot += cb->name_entry_size;
+ }
+
+PUT2(slot, 0, groupno);
+memcpy(slot + IMM2_SIZE, name, CU2BYTES(length));
+
+/* Add a terminating zero and fill the rest of the slot with zeroes so that
+the memory is all initialized. Otherwise valgrind moans about uninitialized
+memory when saving serialized compiled patterns. */
+
+memset(slot + IMM2_SIZE + length, 0,
+ CU2BYTES(cb->name_entry_size - length - IMM2_SIZE));
+}
+
+
+
+/*************************************************
+* Skip in parsed pattern *
+*************************************************/
+
+/* This function is called to skip parts of the parsed pattern when finding the
+length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find
+the end of the branch, it is called to skip over an internal lookaround, and it
+is also called to skip to the end of a class, during which it will never
+encounter nested groups (but there's no need to have special code for that).
+
+Arguments:
+ pptr current pointer to skip from
+ skiptype PSKIP_CLASS when skipping to end of class
+ PSKIP_ALT when META_ALT ends the skip
+ PSKIP_KET when only META_KET ends the skip
+
+Returns: new value of pptr
+ NULL if META_END is reached - should never occur
+ or for an unknown meta value - likewise
+*/
+
+static uint32_t *
+parsed_skip(uint32_t *pptr, uint32_t skiptype)
+{
+uint32_t nestlevel = 0;
+
+for (pptr += 1;; pptr++)
+ {
+ uint32_t meta = META_CODE(*pptr);
+
+ switch(meta)
+ {
+ default: /* Just skip over most items */
+ if (meta < META_END) continue; /* Literal */
+ break;
+
+ /* This should never occur. */
+
+ case META_END:
+ return NULL;
+
+ /* The data for these items is variable in length. */
+
+ case META_BACKREF: /* Offset is present only if group >= 10 */
+ if (META_DATA(*pptr) >= 10) pptr += SIZEOFFSET;
+ break;
+
+ case META_ESCAPE: /* A few escapes are followed by data items. */
+ switch (META_DATA(*pptr))
+ {
+ case ESC_P:
+ case ESC_p:
+ pptr += 1;
+ break;
+
+ case ESC_g:
+ case ESC_k:
+ pptr += 1 + SIZEOFFSET;
+ break;
+ }
+ break;
+
+ case META_MARK: /* Add the length of the name. */
+ case META_PRUNE_ARG:
+ case META_SKIP_ARG:
+ case META_THEN_ARG:
+ pptr += pptr[1];
+ break;
+
+ /* These are the "active" items in this loop. */
+
+ case META_CLASS_END:
+ if (skiptype == PSKIP_CLASS) return pptr;
+ break;
+
+ case META_ATOMIC:
+ case META_CAPTURE:
+ case META_COND_ASSERT:
+ case META_COND_DEFINE:
+ case META_COND_NAME:
+ case META_COND_NUMBER:
+ case META_COND_RNAME:
+ case META_COND_RNUMBER:
+ case META_COND_VERSION:
+ case META_LOOKAHEAD:
+ case META_LOOKAHEADNOT:
+ case META_LOOKBEHIND:
+ case META_LOOKBEHINDNOT:
+ case META_NOCAPTURE:
+ nestlevel++;
+ break;
+
+ case META_ALT:
+ if (nestlevel == 0 && skiptype == PSKIP_ALT) return pptr;
+ break;
+
+ case META_KET:
+ if (nestlevel == 0) return pptr;
+ nestlevel--;
+ break;
+ }
+
+ /* The extra data item length for each meta is in a table. */
+
+ meta = (meta >> 16) & 0x7fff;
+ if (meta >= sizeof(meta_extra_lengths)) return NULL;
+ pptr += meta_extra_lengths[meta];
+ }
+/* Control never reaches here */
+return pptr;
+}
+
+
+
+/*************************************************
+* Find length of a parsed group *
+*************************************************/
+
+/* This is called for nested groups within a branch of a lookbehind whose
+length is being computed. If all the branches in the nested group have the same
+length, that is OK. On entry, the pointer must be at the first element after
+the group initializing code. Caching is used to improve processing speed when
+the same capturing group occurs many times.
+
+Arguments:
+ pptrptr pointer to pointer in the parsed pattern
+ errcodeptr pointer to the errorcode
+ lcptr pointer to the loop counter
+ group number of captured group or -1 for a non-capturing group
+ recurses chain of recurse_check to catch mutual recursion
+ cb pointer to the compile data
+
+Returns: the group length or a negative number
+*/
+
+static int
+get_grouplength(uint32_t **pptrptr, int *errcodeptr, int *lcptr,
+ int group, parsed_recurse_check *recurses, compile_block *cb)
+{
+int branchlength;
+int grouplength = -1;
+
+/* The cache can be used only if there is no possibility of there being two
+groups with the same number. */
+
+if (group > 0)
+ {
+ uint32_t groupinfo = cb->groupinfo[group];
+ if ((cb->external_flags & PCRE2_DUPCAPUSED) == 0)
+ {
+ if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return -1;
+ if ((groupinfo & GI_SET_FIXED_LENGTH) != 0)
+ return groupinfo & GI_FIXED_LENGTH_MASK;
+ }
+ }
+
+/* Scan the group */
+
+for(;;)
+ {
+ branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb);
+ if (branchlength < 0) goto ISNOTFIXED;
+ if (grouplength == -1) grouplength = branchlength;
+ else if (grouplength != branchlength) goto ISNOTFIXED;
+ if (**pptrptr == META_KET) break;
+ *pptrptr += 1; /* Skip META_ALT */
+ }
+
+if (group > 0)
+ cb->groupinfo[group] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength);
+return grouplength;
+
+ISNOTFIXED:
+if (group > 0) cb->groupinfo[group] |= GI_NOT_FIXED_LENGTH;
+return -1;
+}
+
+
+
+/*************************************************
+* Find length of a parsed branch *
+*************************************************/
+
+/* Return a fixed length for a branch in a lookbehind, giving an error if the
+length is not fixed. If any lookbehinds are encountered on the way, they get
+their length set. On entry, *pptrptr points to the first element inside the
+branch. On exit it is set to point to the ALT or KET.
+
+Arguments:
+ pptrptr pointer to pointer in the parsed pattern
+ errcodeptr pointer to error code
+ lcptr pointer to loop counter
+ recurses chain of recurse_check to catch mutual recursion
+ cb pointer to compile block
+
+Returns: the length, or a negative value on error
+*/
+
+static int
+get_branchlength(uint32_t **pptrptr, int *errcodeptr, int *lcptr,
+ parsed_recurse_check *recurses, compile_block *cb)
+{
+int branchlength = 0;
+int grouplength;
+uint32_t lastitemlength = 0;
+uint32_t *pptr = *pptrptr;
+PCRE2_SIZE offset;
+parsed_recurse_check this_recurse;
+
+/* A large and/or complex regex can take too long to process. This can happen
+more often when (?| groups are present in the pattern because their length
+cannot be cached. */
+
+if ((*lcptr)++ > 2000)
+ {
+ *errcodeptr = ERR35; /* Lookbehind is too complicated */
+ return -1;
+ }
+
+/* Scan the branch, accumulating the length. */
+
+for (;; pptr++)
+ {
+ parsed_recurse_check *r;
+ uint32_t *gptr, *gptrend;
+ uint32_t escape;
+ uint32_t group = 0;
+ uint32_t itemlength = 0;
+
+ if (*pptr < META_END)
+ {
+ itemlength = 1;
+ }
+
+ else switch (META_CODE(*pptr))
+ {
+ case META_KET:
+ case META_ALT:
+ goto EXIT;
+
+ /* (*ACCEPT) and (*FAIL) terminate the branch, but we must skip to the
+ actual termination. */
+
+ case META_ACCEPT:
+ case META_FAIL:
+ pptr = parsed_skip(pptr, PSKIP_ALT);
+ if (pptr == NULL) goto PARSED_SKIP_FAILED;
+ goto EXIT;
+
+ case META_MARK:
+ case META_PRUNE_ARG:
+ case META_SKIP_ARG:
+ case META_THEN_ARG:
+ pptr += pptr[1] + 1;
+ break;
+
+ case META_CIRCUMFLEX:
+ case META_COMMIT:
+ case META_DOLLAR:
+ case META_PRUNE:
+ case META_SKIP:
+ case META_THEN:
+ break;
+
+ case META_OPTIONS:
+ pptr += 1;
+ break;
+
+ case META_BIGVALUE:
+ itemlength = 1;
+ pptr += 1;
+ break;
+
+ case META_CLASS:
+ case META_CLASS_NOT:
+ itemlength = 1;
+ pptr = parsed_skip(pptr, PSKIP_CLASS);
+ if (pptr == NULL) goto PARSED_SKIP_FAILED;
+ break;
+
+ case META_CLASS_EMPTY_NOT:
+ case META_DOT:
+ itemlength = 1;
+ break;
+
+ case META_CALLOUT_NUMBER:
+ pptr += 3;
+ break;
+
+ case META_CALLOUT_STRING:
+ pptr += 3 + SIZEOFFSET;
+ break;
+
+ /* Only some escapes consume a character. Of those, \R and \X are never
+ allowed because they might match more than character. \C is allowed only in
+ 32-bit and non-UTF 8/16-bit modes. */
+
+ case META_ESCAPE:
+ escape = META_DATA(*pptr);
+ if (escape == ESC_R || escape == ESC_X) return -1;
+ if (escape > ESC_b && escape < ESC_Z)
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ if ((cb->external_options & PCRE2_UTF) != 0 && escape == ESC_C)
+ {
+ *errcodeptr = ERR36;
+ return -1;
+ }
+#endif
+ itemlength = 1;
+ if (escape == ESC_p || escape == ESC_P) pptr++; /* Skip prop data */
+ }
+ break;
+
+ /* Lookaheads can be ignored. */
+
+ case META_LOOKAHEAD:
+ case META_LOOKAHEADNOT:
+ pptr = parsed_skip(pptr, PSKIP_KET);
+ if (pptr == NULL) goto PARSED_SKIP_FAILED;
+ break;
+
+ /* Lookbehinds can be ignored, but must themselves be checked. */
+
+ case META_LOOKBEHIND:
+ case META_LOOKBEHINDNOT:
+ if (!set_lookbehind_lengths(&pptr, errcodeptr, lcptr, recurses, cb))
+ return -1;
+ break;
+
+ /* Back references and recursions are handled by very similar code. At this
+ stage, the names generated in the parsing pass are available, but the main
+ name table has not yet been created. So for the named varieties, scan the
+ list of names in order to get the number of the first one in the pattern,
+ and whether or not this name is duplicated. */
+
+ case META_BACKREF_BYNAME:
+ if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0)
+ goto ISNOTFIXED;
+
+ case META_RECURSE_BYNAME:
+ {
+ int i;
+ PCRE2_SPTR name;
+ BOOL is_dupname = FALSE;
+ named_group *ng = cb->named_groups;
+ uint32_t meta_code = META_CODE(*pptr);
+ uint32_t length = *(++pptr);
+
+ GETPLUSOFFSET(offset, pptr);
+ name = cb->start_pattern + offset;
+ for (i = 0; i < cb->names_found; i++, ng++)
+ {
+ if (length == ng->length && PRIV(strncmp)(name, ng->name, length) == 0)
+ {
+ group = ng->number;
+ is_dupname = ng->isdup;
+ break;
+ }
+ }
+
+ if (group == 0)
+ {
+ *errcodeptr = ERR15; /* Non-existent subpattern */
+ cb->erroroffset = offset;
+ return -1;
+ }
+
+ /* A numerical back reference can be fixed length if duplicate capturing
+ groups are not being used. A non-duplicate named back reference can also
+ be handled. */
+
+ if (meta_code == META_RECURSE_BYNAME ||
+ (!is_dupname && (cb->external_flags & PCRE2_DUPCAPUSED) == 0))
+ goto RECURSE_OR_BACKREF_LENGTH; /* Handle as a numbered version. */
+ }
+ goto ISNOTFIXED; /* Duplicate name or number */
+
+ /* The offset values for back references < 10 are in a separate vector
+ because otherwise they would use more than two parsed pattern elements on
+ 64-bit systems. */
+
+ case META_BACKREF:
+ if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0 ||
+ (cb->external_flags & PCRE2_DUPCAPUSED) != 0)
+ goto ISNOTFIXED;
+ group = META_DATA(*pptr);
+ if (group < 10)
+ {
+ offset = cb->small_ref_offset[group];
+ goto RECURSE_OR_BACKREF_LENGTH;
+ }
+
+ /* Fall through for groups >= 10 - picking up group twice does no harm. */
+
+ /* A true recursion implies not fixed length, but a subroutine call may
+ be OK. Back reference "recursions" are also failed. */
+
+ case META_RECURSE:
+ group = META_DATA(*pptr);
+ GETPLUSOFFSET(offset, pptr);
+
+ RECURSE_OR_BACKREF_LENGTH:
+ if (group > cb->bracount)
+ {
+ cb->erroroffset = offset;
+ *errcodeptr = ERR15; /* Non-existent subpattern */
+ return -1;
+ }
+ if (group == 0) goto ISNOTFIXED; /* Local recursion */
+ for (gptr = cb->parsed_pattern; *gptr != META_END; gptr++)
+ {
+ if (META_CODE(*gptr) == META_BIGVALUE) gptr++;
+ else if (*gptr == (META_CAPTURE | group)) break;
+ }
+
+ gptrend = parsed_skip(gptr, PSKIP_KET);
+ if (gptrend == NULL) goto PARSED_SKIP_FAILED;
+ if (pptr > gptr && pptr < gptrend) goto ISNOTFIXED; /* Local recursion */
+ for (r = recurses; r != NULL; r = r->prev) if (r->groupptr == gptr) break;
+ if (r != NULL) goto ISNOTFIXED; /* Mutual recursion */
+ this_recurse.prev = recurses;
+ this_recurse.groupptr = gptr;
+ gptr++;
+ grouplength = get_grouplength(&gptr, errcodeptr, lcptr, group,
+ &this_recurse, cb);
+ if (grouplength < 0)
+ {
+ if (*errcodeptr == 0) goto ISNOTFIXED;
+ return -1; /* Error already set */
+ }
+ itemlength = grouplength;
+ break;
+
+ /* Check nested groups - advance past the initial data for each type and
+ then seek a fixed length with get_grouplength(). */
+
+ case META_COND_NAME:
+ case META_COND_NUMBER:
+ case META_COND_RNAME:
+ case META_COND_RNUMBER:
+ case META_COND_DEFINE:
+ pptr += 2 + SIZEOFFSET;
+ goto CHECK_GROUP;
+
+ case META_COND_ASSERT:
+ pptr += 1;
+ goto CHECK_GROUP;
+
+ case META_COND_VERSION:
+ pptr += 4;
+ goto CHECK_GROUP;
+
+ case META_CAPTURE:
+ group = META_DATA(*pptr);
+ /* Fall through */
+
+ case META_ATOMIC:
+ case META_NOCAPTURE:
+ pptr++;
+ CHECK_GROUP:
+ grouplength = get_grouplength(&pptr, errcodeptr, lcptr, group, recurses, cb);
+ if (grouplength < 0) return -1;
+ itemlength = grouplength;
+ break;
+
+ /* Exact repetition is OK; variable repetition is not. A repetition of zero
+ must subtract the length that has already been added. */
+
+ case META_MINMAX:
+ case META_MINMAX_PLUS:
+ case META_MINMAX_QUERY:
+ if (pptr[1] == pptr[2])
+ {
+ if (pptr[1] == 0) branchlength -= lastitemlength;
+ else itemlength = (pptr[1] - 1) * lastitemlength;
+ pptr += 2;
+ break;
+ }
+ /* Fall through */
+
+ /* Any other item means this branch does not have a fixed length. */
+
+ default:
+ ISNOTFIXED:
+ *errcodeptr = ERR25; /* Not fixed length */
+ return -1;
+ }
+
+ /* Add the item length to the branchlength, and save it for use if the next
+ thing is a quantifier. */
+
+ branchlength += itemlength;
+ lastitemlength = itemlength;
+
+ /* Ensure that the length does not overflow the limit. */
+
+ if (branchlength > LOOKBEHIND_MAX)
+ {
+ *errcodeptr = ERR87;
+ return -1;
+ }
+ }
+
+EXIT:
+*pptrptr = pptr;
+if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength;
+return branchlength;
+
+PARSED_SKIP_FAILED:
+*errcodeptr = ERR90;
+return -1;
+}
+
+
+
+/*************************************************
+* Set lengths in a lookbehind *
+*************************************************/
+
+/* This function is called for each lookbehind, to set the lengths in its
+branches. An error occurs if any branch does not have a fixed length that is
+less than the maximum (65535). On exit, the pointer must be left on the final
+ket.
+
+Arguments:
+ pptrptr pointer to pointer in the parsed pattern
+ errcodeptr pointer to error code
+ lcptr pointer to loop counter
+ recurses chain of recurse_check to catch mutual recursion
+ cb pointer to compile block
+
+Returns: TRUE if all is well
+ FALSE otherwise, with error code and offset set
+*/
+
+static BOOL
+set_lookbehind_lengths(uint32_t **pptrptr, int *errcodeptr, int *lcptr,
+ parsed_recurse_check *recurses, compile_block *cb)
+{
+PCRE2_SIZE offset;
+int branchlength;
+uint32_t *bptr = *pptrptr;
+
+READPLUSOFFSET(offset, bptr); /* Offset for error messages */
+*pptrptr += SIZEOFFSET;
+
+do
+ {
+ *pptrptr += 1;
+ branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb);
+ if (branchlength < 0)
+ {
+ /* The errorcode and offset may already be set from a nested lookbehind. */
+ if (*errcodeptr == 0) *errcodeptr = ERR25;
+ if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset;
+ return FALSE;
+ }
+ *bptr |= branchlength; /* branchlength never more than 65535 */
+ bptr = *pptrptr;
+ }
+while (*bptr == META_ALT);
+
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check parsed pattern lookbehinds *
+*************************************************/
+
+/* This function is called at the end of parsing a pattern if any lookbehinds
+were encountered. It scans the parsed pattern for them, calling
+set_lookbehind_lengths() for each one. At the start, the errorcode is zero and
+the error offset is marked unset. The enables the functions above not to
+override settings from deeper nestings.
+
+Arguments cb points to the compile block
+Returns: 0 on success, or an errorcode (cb->erroroffset will be set)
+*/
+
+static int
+check_lookbehinds(compile_block *cb)
+{
+uint32_t *pptr;
+int errorcode = 0;
+int loopcount = 0;
+
+cb->erroroffset = PCRE2_UNSET;
+
+for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
+ {
+ if (*pptr < META_END) continue; /* Literal */
+
+ switch (META_CODE(*pptr))
+ {
+ default:
+ return ERR70; /* Unrecognized meta code */
+
+ case META_ESCAPE:
+ if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p)
+ pptr += 1;
+ break;
+
+ case META_ACCEPT:
+ case META_ALT:
+ case META_ASTERISK:
+ case META_ASTERISK_PLUS:
+ case META_ASTERISK_QUERY:
+ case META_ATOMIC:
+ case META_BACKREF:
+ case META_CAPTURE:
+ case META_CIRCUMFLEX:
+ case META_CLASS:
+ case META_CLASS_EMPTY:
+ case META_CLASS_EMPTY_NOT:
+ case META_CLASS_END:
+ case META_CLASS_NOT:
+ case META_COMMIT:
+ case META_COND_ASSERT:
+ case META_DOLLAR:
+ case META_DOT:
+ case META_FAIL:
+ case META_KET:
+ case META_LOOKAHEAD:
+ case META_LOOKAHEADNOT:
+ case META_NOCAPTURE:
+ case META_PLUS:
+ case META_PLUS_PLUS:
+ case META_PLUS_QUERY:
+ case META_PRUNE:
+ case META_QUERY:
+ case META_QUERY_PLUS:
+ case META_QUERY_QUERY:
+ case META_RANGE_ESCAPED:
+ case META_RANGE_LITERAL:
+ case META_SKIP:
+ case META_THEN:
+ break;
+
+ case META_RECURSE:
+ pptr += SIZEOFFSET;
+ break;
+
+ case META_BACKREF_BYNAME:
+ case META_COND_DEFINE:
+ case META_COND_NAME:
+ case META_COND_NUMBER:
+ case META_COND_RNAME:
+ case META_COND_RNUMBER:
+ case META_RECURSE_BYNAME:
+ pptr += 1 + SIZEOFFSET;
+ break;
+
+ case META_CALLOUT_STRING:
+ pptr += 3 + SIZEOFFSET;
+ break;
+
+ case META_BIGVALUE:
+ case META_OPTIONS:
+ case META_POSIX:
+ case META_POSIX_NEG:
+ pptr += 1;
+ break;
+
+ case META_MINMAX:
+ case META_MINMAX_QUERY:
+ case META_MINMAX_PLUS:
+ pptr += 2;
+ break;
+
+ case META_CALLOUT_NUMBER:
+ case META_COND_VERSION:
+ pptr += 3;
+ break;
+
+ case META_MARK:
+ case META_PRUNE_ARG:
+ case META_SKIP_ARG:
+ case META_THEN_ARG:
+ pptr += 1 + pptr[1];
+ break;
+
+ case META_LOOKBEHIND:
+ case META_LOOKBEHINDNOT:
+ if (!set_lookbehind_lengths(&pptr, &errorcode, &loopcount, NULL, cb))
+ return errorcode;
+ break;
+ }
+ }
+
+return 0;
+}
+
+
+
+/*************************************************
+* External function to compile a pattern *
+*************************************************/
+
+/* This function reads a regular expression in the form of a string and returns
+a pointer to a block of store holding a compiled version of the expression.
+
+Arguments:
+ pattern the regular expression
+ patlen the length of the pattern, or PCRE2_ZERO_TERMINATED
+ options option bits
+ errorptr pointer to errorcode
+ erroroffset pointer to error offset
+ ccontext points to a compile context or is NULL
+
+Returns: pointer to compiled data block, or NULL on error,
+ with errorcode and erroroffset set
+*/
+
+PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
+pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options,
+ int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext)
+{
+BOOL utf; /* Set TRUE for UTF mode */
+BOOL has_lookbehind; /* Set TRUE if a lookbehind is found */
+BOOL zero_terminated; /* Set TRUE for zero-terminated pattern */
+pcre2_real_code *re = NULL; /* What we will return */
+compile_block cb; /* "Static" compile-time data */
+const uint8_t *tables; /* Char tables base pointer */
+
+PCRE2_UCHAR *code; /* Current pointer in compiled code */
+PCRE2_SPTR codestart; /* Start of compiled code */
+PCRE2_SPTR ptr; /* Current pointer in pattern */
+uint32_t *pptr; /* Current pointer in parsed pattern */
+
+PCRE2_SIZE length = 1; /* Allow for final END opcode */
+PCRE2_SIZE usedlength; /* Actual length used */
+PCRE2_SIZE re_blocksize; /* Size of memory block */
+PCRE2_SIZE big32count = 0; /* 32-bit literals >= 0x80000000 */
+PCRE2_SIZE parsed_size_needed; /* Needed for parsed pattern */
+
+int32_t firstcuflags, reqcuflags; /* Type of first/req code unit */
+uint32_t firstcu, reqcu; /* Value of first/req code unit */
+uint32_t setflags = 0; /* NL and BSR set flags */
+
+uint32_t skipatstart; /* When checking (*UTF) etc */
+uint32_t limit_match = UINT32_MAX; /* Unset match limits */
+uint32_t limit_recursion = UINT32_MAX;
+
+int newline = 0; /* Unset; can be set by the pattern */
+int bsr = 0; /* Unset; can be set by the pattern */
+int errorcode = 0; /* Initialize to avoid compiler warn */
+int regexrc; /* Return from compile */
+
+uint32_t i; /* Local loop counter */
+
+/* Comments at the head of this file explain about these variables. */
+
+uint32_t stack_groupinfo[GROUPINFO_DEFAULT_SIZE];
+uint32_t stack_parsed_pattern[PARSED_PATTERN_DEFAULT_SIZE];
+named_group named_groups[NAMED_GROUP_LIST_SIZE];
+
+/* The workspace is used in different ways in the different compiling phases.
+It needs to be 16-bit aligned for the preliminary parsing scan. */
+
+uint32_t c16workspace[C16_WORK_SIZE];
+PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c16workspace;
+
+
+/* -------------- Check arguments and set up the pattern ----------------- */
+
+/* There must be error code and offset pointers. */
+
+if (errorptr == NULL || erroroffset == NULL) return NULL;
+*errorptr = ERR0;
+*erroroffset = 0;
+
+/* There must be a pattern! */
+
+if (pattern == NULL)
+ {
+ *errorptr = ERR16;
+ return NULL;
+ }
+
+/* Check that all undefined public option bits are zero. */
+
+if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
+ {
+ *errorptr = ERR17;
+ return NULL;
+ }
+
+/* A NULL compile context means "use a default context" */
+
+if (ccontext == NULL)
+ ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context));
+
+/* A zero-terminated pattern is indicated by the special length value
+PCRE2_ZERO_TERMINATED. Check for an overlong pattern. */
+
+if ((zero_terminated = (patlen == PCRE2_ZERO_TERMINATED)))
+ patlen = PRIV(strlen)(pattern);
+
+if (patlen > ccontext->max_pattern_length)
+ {
+ *errorptr = ERR88;
+ return NULL;
+ }
+
+/* From here on, all returns from this function should end up going via the
+EXIT label. */
+
+
+/* ------------ Initialize the "static" compile data -------------- */
+
+tables = (ccontext->tables != NULL)? ccontext->tables : PRIV(default_tables);
+
+cb.lcc = tables + lcc_offset; /* Individual */
+cb.fcc = tables + fcc_offset; /* character */
+cb.cbits = tables + cbits_offset; /* tables */
+cb.ctypes = tables + ctypes_offset;
+
+cb.assert_depth = 0;
+cb.bracount = 0;
+cb.cx = ccontext;
+cb.dupnames = FALSE;
+cb.end_pattern = pattern + patlen;
+cb.erroroffset = 0;
+cb.external_flags = 0;
+cb.external_options = options;
+cb.groupinfo = stack_groupinfo;
+cb.had_recurse = FALSE;
+cb.lastcapture = 0;
+cb.max_lookbehind = 0;
+cb.name_entry_size = 0;
+cb.name_table = NULL;
+cb.named_groups = named_groups;
+cb.named_group_list_size = NAMED_GROUP_LIST_SIZE;
+cb.names_found = 0;
+cb.open_caps = NULL;
+cb.parens_depth = 0;
+cb.parsed_pattern = stack_parsed_pattern;
+cb.req_varyopt = 0;
+cb.start_code = cworkspace;
+cb.start_pattern = pattern;
+cb.start_workspace = cworkspace;
+cb.workspace_size = COMPILE_WORK_SIZE;
+
+/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
+references to help in deciding whether (.*) can be treated as anchored or not.
+*/
+
+cb.top_backref = 0;
+cb.backref_map = 0;
+
+/* Escape sequences \1 to \9 are always back references, but as they are only
+two characters long, only two elements can be used in the parsed_pattern
+vector. The first contains the reference, and we'd like to use the second to
+record the offset in the pattern, so that forward references to non-existent
+groups can be diagnosed later with an offset. However, on 64-bit systems,
+PCRE2_SIZE won't fit. Instead, we have a vector of offsets for the first
+occurrence of \1 to \9, indexed by the second parsed_pattern value. All other
+references have enough space for the offset to be put into the parsed pattern.
+*/
+
+for (i = 0; i < 10; i++) cb.small_ref_offset[i] = PCRE2_UNSET;
+
+
+/* --------------- Start looking at the pattern --------------- */
+
+/* Check for global one-time option settings at the start of the pattern, and
+remember the offset to the actual regex. With valgrind support, make the
+terminator of a zero-terminated pattern inaccessible. This catches bugs that
+would otherwise only show up for non-zero-terminated patterns. */
+
+#ifdef SUPPORT_VALGRIND
+if (zero_terminated) VALGRIND_MAKE_MEM_NOACCESS(pattern + patlen, CU2BYTES(1));
+#endif
+
+ptr = pattern;
+skipatstart = 0;
+
+while (patlen - skipatstart >= 2 &&
+ ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
+ ptr[skipatstart+1] == CHAR_ASTERISK)
+ {
+ for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++)
+ {
+ pso *p = pso_list + i;
+
+ if (patlen - skipatstart - 2 >= p->length &&
+ PRIV(strncmp_c8)(ptr+skipatstart+2, (char *)(p->name), p->length) == 0)
+ {
+ uint32_t c, pp;
+
+ skipatstart += p->length + 2;
+ switch(p->type)
+ {
+ case PSO_OPT:
+ cb.external_options |= p->value;
+ break;
+
+ case PSO_FLG:
+ setflags |= p->value;
+ break;
+
+ case PSO_NL:
+ newline = p->value;
+ setflags |= PCRE2_NL_SET;
+ break;
+
+ case PSO_BSR:
+ bsr = p->value;
+ setflags |= PCRE2_BSR_SET;
+ break;
+
+ case PSO_LIMM:
+ case PSO_LIMR:
+ c = 0;
+ pp = skipatstart;
+ if (!IS_DIGIT(ptr[pp]))
+ {
+ errorcode = ERR60;
+ ptr += pp;
+ goto HAD_EARLY_ERROR;
+ }
+ while (IS_DIGIT(ptr[pp]))
+ {
+ if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */
+ c = c*10 + (ptr[pp++] - CHAR_0);
+ }
+ if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS)
+ {
+ errorcode = ERR60;
+ ptr += pp;
+ goto HAD_EARLY_ERROR;
+ }
+ if (p->type == PSO_LIMM) limit_match = c;
+ else limit_recursion = c;
+ skipatstart += pp - skipatstart;
+ break;
+ }
+ break; /* Out of the table scan loop */
+ }
+ }
+ if (i >= sizeof(pso_list)/sizeof(pso)) break; /* Out of pso loop */
+ }
+
+/* End of pattern-start options; advance to start of real regex. */
+
+ptr += skipatstart;
+
+/* Can't support UTF or UCP unless PCRE2 has been compiled with UTF support. */
+
+#ifndef SUPPORT_UNICODE
+if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0)
+ {
+ errorcode = ERR32;
+ goto HAD_EARLY_ERROR;
+ }
+#endif
+
+/* Check UTF. We have the original options in 'options', with that value as
+modified by (*UTF) etc in cb->external_options. */
+
+utf = (cb.external_options & PCRE2_UTF) != 0;
+if (utf)
+ {
+ if ((options & PCRE2_NEVER_UTF) != 0)
+ {
+ errorcode = ERR74;
+ goto HAD_EARLY_ERROR;
+ }
+ if ((options & PCRE2_NO_UTF_CHECK) == 0 &&
+ (errorcode = PRIV(valid_utf)(pattern, patlen, erroroffset)) != 0)
+ goto HAD_ERROR; /* Offset was set by valid_utf() */
+ }
+
+/* Check UCP lockout. */
+
+if ((cb.external_options & (PCRE2_UCP|PCRE2_NEVER_UCP)) ==
+ (PCRE2_UCP|PCRE2_NEVER_UCP))
+ {
+ errorcode = ERR75;
+ goto HAD_EARLY_ERROR;
+ }
+
+/* Process the BSR setting. */
+
+if (bsr == 0) bsr = ccontext->bsr_convention;
+
+/* Process the newline setting. */
+
+if (newline == 0) newline = ccontext->newline_convention;
+cb.nltype = NLTYPE_FIXED;
+switch(newline)
+ {
+ case PCRE2_NEWLINE_CR:
+ cb.nllen = 1;
+ cb.nl[0] = CHAR_CR;
+ break;
+
+ case PCRE2_NEWLINE_LF:
+ cb.nllen = 1;
+ cb.nl[0] = CHAR_NL;
+ break;
+
+ case PCRE2_NEWLINE_CRLF:
+ cb.nllen = 2;
+ cb.nl[0] = CHAR_CR;
+ cb.nl[1] = CHAR_NL;
+ break;
+
+ case PCRE2_NEWLINE_ANY:
+ cb.nltype = NLTYPE_ANY;
+ break;
+
+ case PCRE2_NEWLINE_ANYCRLF:
+ cb.nltype = NLTYPE_ANYCRLF;
+ break;
+
+ default:
+ errorcode = ERR56;
+ goto HAD_EARLY_ERROR;
+ }
+
+/* Pre-scan the pattern to do two things: (1) Discover the named groups and
+their numerical equivalents, so that this information is always available for
+the remaining processing. (2) At the same time, parse the pattern and put a
+processed version into the parsed_pattern vector. This has escapes interpreted
+and comments removed (amongst other things).
+
+In all but one case, when PCRE2_AUTO_CALLOUT is not set, the number of unsigned
+32-bit ints in the parsed pattern is bounded by the length of the pattern plus
+one (for the terminator). The exceptional case is when running in 32-bit,
+non-UTF mode, when literal characters greater than META_END (0x80000000) have
+to be coded as two units. In this case, therefore, we scan the pattern to check
+for such values. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 32
+if (!utf)
+ {
+ PCRE2_SPTR p;
+ for (p = ptr; p < cb.end_pattern; p++) if (*p >= META_END) big32count++;
+ }
+#endif
+
+/* Ensure that the parsed pattern buffer is big enough. When PCRE2_AUTO_CALLOUT
+is set we have to assume a numerical callout (4 elements) for each character
+plus one at the end. This is overkill, but memory is plentiful these days. For
+many smaller patterns the vector on the stack (which was set up above) can be
+used. */
+
+parsed_size_needed = patlen - skipatstart + big32count;
+if ((options & PCRE2_AUTO_CALLOUT) != 0)
+ parsed_size_needed = (parsed_size_needed + 1) * 5;
+
+if (parsed_size_needed >= PARSED_PATTERN_DEFAULT_SIZE)
+ {
+ uint32_t *heap_parsed_pattern = ccontext->memctl.malloc(
+ (parsed_size_needed + 1) * sizeof(uint32_t), ccontext->memctl.memory_data);
+ if (heap_parsed_pattern == NULL)
+ {
+ *errorptr = ERR21;
+ goto EXIT;
+ }
+ cb.parsed_pattern = heap_parsed_pattern;
+ }
+cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1;
+
+/* Do the parsing scan. */
+
+errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb);
+if (errorcode != 0) goto HAD_CB_ERROR;
+
+/* Workspace is needed to remember information about numbered groups: whether a
+group can match an empty string and what its fixed length is. This is done to
+avoid the possibility of recursive references causing very long compile times
+when checking these features. Unnumbered groups do not have this exposure since
+they cannot be referenced. We use an indexed vector for this purpose. If there
+are sufficiently few groups, the default vector on the stack, as set up above,
+can be used. Otherwise we have to get/free a special vector. The vector must be
+initialized to zero. */
+
+if (cb.bracount >= GROUPINFO_DEFAULT_SIZE)
+ {
+ cb.groupinfo = ccontext->memctl.malloc(
+ (cb.bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data);
+ if (cb.groupinfo == NULL)
+ {
+ errorcode = ERR21;
+ cb.erroroffset = 0;
+ goto HAD_CB_ERROR;
+ }
+ }
+memset(cb.groupinfo, 0, (cb.bracount + 1) * sizeof(uint32_t));
+
+/* If there were any lookbehinds, scan the parsed pattern to figure out their
+lengths. */
+
+if (has_lookbehind)
+ {
+ errorcode = check_lookbehinds(&cb);
+ if (errorcode != 0) goto HAD_CB_ERROR;
+ }
+
+/* For debugging, there is a function that shows the parsed data vector. */
+
+#ifdef DEBUG_SHOW_PARSED
+fprintf(stderr, "+++ Pre-scan complete:\n");
+show_parsed(&cb);
+#endif
+
+/* For debugging capturing information this code can be enabled. */
+
+#ifdef DEBUG_SHOW_CAPTURES
+ {
+ named_group *ng = cb.named_groups;
+ fprintf(stderr, "+++Captures: %d\n", cb.bracount);
+ for (i = 0; i < cb.names_found; i++, ng++)
+ {
+ fprintf(stderr, "+++%3d %.*s\n", ng->number, ng->length, ng->name);
+ }
+ }
+#endif
+
+/* Pretend to compile the pattern while actually just accumulating the amount
+of memory required in the 'length' variable. This behaviour is triggered by
+passing a non-NULL final argument to compile_regex(). We pass a block of
+workspace (cworkspace) for it to compile parts of the pattern into; the
+compiled code is discarded when it is no longer needed, so hopefully this
+workspace will never overflow, though there is a test for its doing so.
+
+On error, errorcode will be set non-zero, so we don't need to look at the
+result of the function. The initial options have been put into the cb block,
+but we still have to pass a separate options variable (the first argument)
+because the options may change as the pattern is processed. */
+
+cb.erroroffset = patlen; /* For any subsequent errors that do not set it */
+pptr = cb.parsed_pattern;
+code = cworkspace;
+*code = OP_BRA;
+
+(void)compile_regex(cb.external_options, &code, &pptr, &errorcode, 0, &firstcu,
+ &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, &length);
+
+if (errorcode != 0) goto HAD_CB_ERROR; /* Offset is in cb.erroroffset */
+
+/* This should be caught in compile_regex(), but just in case... */
+
+if (length > MAX_PATTERN_SIZE)
+ {
+ errorcode = ERR20;
+ goto HAD_CB_ERROR;
+ }
+
+/* Compute the size of, and then get and initialize, the data block for storing
+the compiled pattern and names table. Integer overflow should no longer be
+possible because nowadays we limit the maximum value of cb.names_found and
+cb.name_entry_size. */
+
+re_blocksize = sizeof(pcre2_real_code) +
+ CU2BYTES(length + cb.names_found * cb.name_entry_size);
+re = (pcre2_real_code *)
+ ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);
+if (re == NULL)
+ {
+ errorcode = ERR21;
+ goto HAD_CB_ERROR;
+ }
+
+re->memctl = ccontext->memctl;
+re->tables = tables;
+re->executable_jit = NULL;
+memset(re->start_bitmap, 0, 32 * sizeof(uint8_t));
+re->blocksize = re_blocksize;
+re->magic_number = MAGIC_NUMBER;
+re->compile_options = options;
+re->overall_options = cb.external_options;
+re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags;
+re->limit_match = limit_match;
+re->limit_recursion = limit_recursion;
+re->first_codeunit = 0;
+re->last_codeunit = 0;
+re->bsr_convention = bsr;
+re->newline_convention = newline;
+re->max_lookbehind = 0;
+re->minlength = 0;
+re->top_bracket = 0;
+re->top_backref = 0;
+re->name_entry_size = cb.name_entry_size;
+re->name_count = cb.names_found;
+
+/* The basic block is immediately followed by the name table, and the compiled
+code follows after that. */
+
+codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) +
+ re->name_entry_size * re->name_count;
+
+/* Update the compile data block for the actual compile. The starting points of
+the name/number translation table and of the code are passed around in the
+compile data block. The start/end pattern and initial options are already set
+from the pre-compile phase, as is the name_entry_size field. */
+
+cb.parens_depth = 0;
+cb.assert_depth = 0;
+cb.lastcapture = 0;
+cb.name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));
+cb.start_code = codestart;
+cb.req_varyopt = 0;
+cb.had_accept = FALSE;
+cb.had_pruneorskip = FALSE;
+cb.open_caps = NULL;
+
+/* If any named groups were found, create the name/number table from the list
+created in the pre-pass. */
+
+if (cb.names_found > 0)
+ {
+ named_group *ng = cb.named_groups;
+ for (i = 0; i < cb.names_found; i++, ng++)
+ add_name_to_table(&cb, ng->name, ng->length, ng->number, i);
+ }
+
+/* Set up a starting, non-extracting bracket, then compile the expression. On
+error, errorcode will be set non-zero, so we don't need to look at the result
+of the function here. */
+
+pptr = cb.parsed_pattern;
+code = (PCRE2_UCHAR *)codestart;
+*code = OP_BRA;
+regexrc = compile_regex(re->overall_options, &code, &pptr, &errorcode, 0,
+ &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL);
+if (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY;
+re->top_bracket = cb.bracount;
+re->top_backref = cb.top_backref;
+re->max_lookbehind = cb.max_lookbehind;
+
+if (cb.had_accept)
+ {
+ reqcu = 0; /* Must disable after (*ACCEPT) */
+ reqcuflags = REQ_NONE;
+ }
+
+/* Fill in the final opcode and check for disastrous overflow. If no overflow,
+but the estimated length exceeds the really used length, adjust the value of
+re->blocksize, and if valgrind support is configured, mark the extra allocated
+memory as unaddressable, so that any out-of-bound reads can be detected. */
+
+*code++ = OP_END;
+usedlength = code - codestart;
+if (usedlength > length) errorcode = ERR23; else
+ {
+ re->blocksize -= CU2BYTES(length - usedlength);
+#ifdef SUPPORT_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength));
+#endif
+ }
+
+/* Scan the pattern for recursion/subroutine calls and convert the group
+numbers into offsets. Maintain a small cache so that repeated groups containing
+recursions are efficiently handled. */
+
+#define RSCAN_CACHE_SIZE 8
+
+if (errorcode == 0 && cb.had_recurse)
+ {
+ PCRE2_UCHAR *rcode;
+ PCRE2_SPTR rgroup;
+ unsigned int ccount = 0;
+ int start = RSCAN_CACHE_SIZE;
+ recurse_cache rc[RSCAN_CACHE_SIZE];
+
+ for (rcode = (PCRE2_UCHAR *)find_recurse(codestart, utf);
+ rcode != NULL;
+ rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf))
+ {
+ int p, groupnumber;
+
+ groupnumber = (int)GET(rcode, 1);
+ if (groupnumber == 0) rgroup = codestart; else
+ {
+ PCRE2_SPTR search_from = codestart;
+ rgroup = NULL;
+ for (i = 0, p = start; i < ccount; i++, p = (p + 1) & 7)
+ {
+ if (groupnumber == rc[p].groupnumber)
+ {
+ rgroup = rc[p].group;
+ break;
+ }
+
+ /* Group n+1 must always start to the right of group n, so we can save
+ search time below when the new group number is greater than any of the
+ previously found groups. */
+
+ if (groupnumber > rc[p].groupnumber) search_from = rc[p].group;
+ }
+
+ if (rgroup == NULL)
+ {
+ rgroup = PRIV(find_bracket)(search_from, utf, groupnumber);
+ if (rgroup == NULL)
+ {
+ errorcode = ERR53;
+ break;
+ }
+ if (--start < 0) start = RSCAN_CACHE_SIZE - 1;
+ rc[start].groupnumber = groupnumber;
+ rc[start].group = rgroup;
+ if (ccount < RSCAN_CACHE_SIZE) ccount++;
+ }
+ }
+
+ PUT(rcode, 1, rgroup - codestart);
+ }
+ }
+
+/* In rare debugging situations we sometimes need to look at the compiled code
+at this stage. */
+
+#ifdef DEBUG_CALL_PRINTINT
+pcre2_printint(re, stderr, TRUE);
+fprintf(stderr, "Length=%lu Used=%lu\n", length, usedlength);
+#endif
+
+/* Unless disabled, check whether any single character iterators can be
+auto-possessified. The function overwrites the appropriate opcode values, so
+the type of the pointer must be cast. NOTE: the intermediate variable "temp" is
+used in this code because at least one compiler gives a warning about loss of
+"const" attribute if the cast (PCRE2_UCHAR *)codestart is used directly in the
+function call. */
+
+if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0)
+ {
+ PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;
+ if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80;
+ }
+
+/* Failed to compile, or error while post-processing. */
+
+if (errorcode != 0) goto HAD_CB_ERROR;
+
+/* Successful compile. If the anchored option was not passed, set it if
+we can determine that the pattern is anchored by virtue of ^ characters or \A
+or anything else, such as starting with non-atomic .* when DOTALL is set and
+there are no occurrences of *PRUNE or *SKIP (though there is an option to
+disable this case). */
+
+if ((re->overall_options & PCRE2_ANCHORED) == 0 &&
+ is_anchored(codestart, 0, &cb, 0, FALSE))
+ re->overall_options |= PCRE2_ANCHORED;
+
+/* If the pattern is still not anchored and we do not have a first code unit,
+see if there is one that is asserted (these are not saved during the compile
+because they can cause conflicts with actual literals that follow). This code
+need not be obeyed if PCRE2_NO_START_OPTIMIZE is set, as the data it would
+create will not be used. */
+
+if ((re->overall_options & (PCRE2_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0)
+ {
+ if (firstcuflags < 0)
+ firstcu = find_firstassertedcu(codestart, &firstcuflags, FALSE);
+
+ /* Save the data for a first code unit. */
+
+ if (firstcuflags >= 0)
+ {
+ re->first_codeunit = firstcu;
+ re->flags |= PCRE2_FIRSTSET;
+
+ /* Handle caseless first code units. */
+
+ if ((firstcuflags & REQ_CASELESS) != 0)
+ {
+ if (firstcu < 128 || (!utf && firstcu < 255))
+ {
+ if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS;
+ }
+
+ /* The first code unit is > 128 in UTF mode, or > 255 otherwise. In
+ 8-bit UTF mode, codepoints in the range 128-255 are introductory code
+ points and cannot have another case. In 16-bit and 32-bit modes, we can
+ check wide characters when UTF (and therefore UCP) is supported. */
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ else if (firstcu <= MAX_UTF_CODE_POINT &&
+ UCD_OTHERCASE(firstcu) != firstcu)
+ re->flags |= PCRE2_FIRSTCASELESS;
+#endif
+ }
+ }
+
+ /* When there is no first code unit, see if we can set the PCRE2_STARTLINE
+ flag. This is helpful for multiline matches when all branches start with ^
+ and also when all branches start with non-atomic .* for non-DOTALL matches
+ when *PRUNE and SKIP are not present. (There is an option that disables this
+ case.) */
+
+ else if (is_startline(codestart, 0, &cb, 0, FALSE))
+ re->flags |= PCRE2_STARTLINE;
+ }
+
+/* Handle the "required code unit", if one is set. In the case of an anchored
+pattern, do this only if it follows a variable length item in the pattern.
+Again, skip this if PCRE2_NO_START_OPTIMIZE is set. */
+
+if (reqcuflags >= 0 &&
+ ((re->overall_options & (PCRE2_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0 ||
+ (reqcuflags & REQ_VARY) != 0))
+ {
+ re->last_codeunit = reqcu;
+ re->flags |= PCRE2_LASTSET;
+
+ /* Handle caseless required code units as for first code units (above). */
+
+ if ((reqcuflags & REQ_CASELESS) != 0)
+ {
+ if (reqcu < 128 || (!utf && reqcu < 255))
+ {
+ if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
+ }
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu)
+ re->flags |= PCRE2_LASTCASELESS;
+#endif
+ }
+ }
+
+/* Finally, unless PCRE2_NO_START_OPTIMIZE is set, study the compiled pattern
+to set up information such as a bitmap of starting code units and a minimum
+matching length. */
+
+if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 &&
+ PRIV(study)(re) != 0)
+ {
+ errorcode = ERR31;
+ goto HAD_CB_ERROR;
+ }
+
+/* Control ends up here in all cases. When running under valgrind, make a
+pattern's terminating zero defined again. If memory was obtained for the parsed
+version of the pattern, free it before returning. Also free the list of named
+groups if a larger one had to be obtained, and likewise the group information
+vector. */
+
+EXIT:
+#ifdef SUPPORT_VALGRIND
+if (zero_terminated) VALGRIND_MAKE_MEM_DEFINED(pattern + patlen, CU2BYTES(1));
+#endif
+if (cb.parsed_pattern != stack_parsed_pattern)
+ ccontext->memctl.free(cb.parsed_pattern, ccontext->memctl.memory_data);
+if (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE)
+ ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data);
+if (cb.groupinfo != stack_groupinfo)
+ ccontext->memctl.free((void *)cb.groupinfo, ccontext->memctl.memory_data);
+return re; /* Will be NULL after an error */
+
+/* Errors discovered in parse_regex() set the offset value in the compile
+block. Errors discovered before it is called must compute it from the ptr
+value. After parse_regex() is called, the offset in the compile block is set to
+the end of the pattern, but certain errors in compile_regex() may reset it if
+an offset is available in the parsed pattern. */
+
+HAD_CB_ERROR:
+ptr = pattern + cb.erroroffset;
+
+HAD_EARLY_ERROR:
+*erroroffset = ptr - pattern;
+
+HAD_ERROR:
+*errorptr = errorcode;
+pcre2_code_free(re);
+re = NULL;
+goto EXIT;
+}
+
+/* End of pcre2_compile.c */
diff --git a/thirdparty/pcre2/src/pcre2_config.c b/thirdparty/pcre2/src/pcre2_config.c
new file mode 100644
index 0000000000..e99272f577
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_config.c
@@ -0,0 +1,218 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes
+its value gets changed by pcre2_internal.h to be in code units. */
+
+static int configured_link_size = LINK_SIZE;
+
+#include "pcre2_internal.h"
+
+/* These macros are the standard way of turning unquoted text into C strings.
+They allow macros like PCRE2_MAJOR to be defined without quotes, which is
+convenient for user programs that want to test their values. */
+
+#define STRING(a) # a
+#define XSTRING(s) STRING(s)
+
+
+/*************************************************
+* Return info about what features are configured *
+*************************************************/
+
+/* If where is NULL, the length of memory required is returned.
+
+Arguments:
+ what what information is required
+ where where to put the information
+
+Returns: 0 if a numerical value is returned
+ >= 0 if a string value
+ PCRE2_ERROR_BADOPTION if "where" not recognized
+ or JIT target requested when JIT not enabled
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_config(uint32_t what, void *where)
+{
+if (where == NULL) /* Requests a length */
+ {
+ switch(what)
+ {
+ default:
+ return PCRE2_ERROR_BADOPTION;
+
+ case PCRE2_CONFIG_BSR:
+ case PCRE2_CONFIG_JIT:
+ case PCRE2_CONFIG_LINKSIZE:
+ case PCRE2_CONFIG_MATCHLIMIT:
+ case PCRE2_CONFIG_NEWLINE:
+ case PCRE2_CONFIG_PARENSLIMIT:
+ case PCRE2_CONFIG_RECURSIONLIMIT:
+ case PCRE2_CONFIG_STACKRECURSE:
+ case PCRE2_CONFIG_UNICODE:
+ return sizeof(uint32_t);
+
+ /* These are handled below */
+
+ case PCRE2_CONFIG_JITTARGET:
+ case PCRE2_CONFIG_UNICODE_VERSION:
+ case PCRE2_CONFIG_VERSION:
+ break;
+ }
+ }
+
+switch (what)
+ {
+ default:
+ return PCRE2_ERROR_BADOPTION;
+
+ case PCRE2_CONFIG_BSR:
+#ifdef BSR_ANYCRLF
+ *((uint32_t *)where) = PCRE2_BSR_ANYCRLF;
+#else
+ *((uint32_t *)where) = PCRE2_BSR_UNICODE;
+#endif
+ break;
+
+ case PCRE2_CONFIG_JIT:
+#ifdef SUPPORT_JIT
+ *((uint32_t *)where) = 1;
+#else
+ *((uint32_t *)where) = 0;
+#endif
+ break;
+
+ case PCRE2_CONFIG_JITTARGET:
+#ifdef SUPPORT_JIT
+ {
+ const char *v = PRIV(jit_get_target)();
+ return (int)(1 + ((where == NULL)?
+ strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
+ }
+#else
+ return PCRE2_ERROR_BADOPTION;
+#endif
+
+ case PCRE2_CONFIG_LINKSIZE:
+ *((uint32_t *)where) = (uint32_t)configured_link_size;
+ break;
+
+ case PCRE2_CONFIG_MATCHLIMIT:
+ *((uint32_t *)where) = MATCH_LIMIT;
+ break;
+
+ case PCRE2_CONFIG_NEWLINE:
+ *((uint32_t *)where) = NEWLINE_DEFAULT;
+ break;
+
+ case PCRE2_CONFIG_PARENSLIMIT:
+ *((uint32_t *)where) = PARENS_NEST_LIMIT;
+ break;
+
+ case PCRE2_CONFIG_RECURSIONLIMIT:
+ *((uint32_t *)where) = MATCH_LIMIT_RECURSION;
+ break;
+
+ case PCRE2_CONFIG_STACKRECURSE:
+#ifdef HEAP_MATCH_RECURSE
+ *((uint32_t *)where) = 0;
+#else
+ *((uint32_t *)where) = 1;
+#endif
+ break;
+
+ case PCRE2_CONFIG_UNICODE_VERSION:
+ {
+#if defined SUPPORT_UNICODE
+ const char *v = PRIV(unicode_version);
+#else
+ const char *v = "Unicode not supported";
+#endif
+ return (int)(1 + ((where == NULL)?
+ strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
+ }
+ break;
+
+ case PCRE2_CONFIG_UNICODE:
+#if defined SUPPORT_UNICODE
+ *((uint32_t *)where) = 1;
+#else
+ *((uint32_t *)where) = 0;
+#endif
+ break;
+
+ /* The hackery in setting "v" below is to cope with the case when
+ PCRE2_PRERELEASE is set to an empty string (which it is for real releases).
+ If the second alternative is used in this case, it does not leave a space
+ before the date. On the other hand, if all four macros are put into a single
+ XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted.
+ There are problems using an "obvious" approach like this:
+
+ XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR)
+ XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE)
+
+ because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion
+ of STRING(). The C standard states: "If (before argument substitution) any
+ argument consists of no preprocessing tokens, the behavior is undefined." It
+ turns out the gcc treats this case as a single empty string - which is what
+ we really want - but Visual C grumbles about the lack of an argument for the
+ macro. Unfortunately, both are within their rights. As there seems to be no
+ way to test for a macro's value being empty at compile time, we have to
+ resort to a runtime test. */
+
+ case PCRE2_CONFIG_VERSION:
+ {
+ const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)?
+ XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) :
+ XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE);
+ return (int)(1 + ((where == NULL)?
+ strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
+ }
+ }
+
+return 0;
+}
+
+/* End of pcre2_config.c */
diff --git a/thirdparty/pcre2/src/pcre2_context.c b/thirdparty/pcre2/src/pcre2_context.c
new file mode 100644
index 0000000000..ae050fe92c
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_context.c
@@ -0,0 +1,391 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+
+/*************************************************
+* Default malloc/free functions *
+*************************************************/
+
+/* Ignore the "user data" argument in each case. */
+
+static void *default_malloc(size_t size, void *data)
+{
+(void)data;
+return malloc(size);
+}
+
+
+static void default_free(void *block, void *data)
+{
+(void)data;
+free(block);
+}
+
+
+
+/*************************************************
+* Get a block and save memory control *
+*************************************************/
+
+/* This internal function is called to get a block of memory in which the
+memory control data is to be stored at the start for future use.
+
+Arguments:
+ size amount of memory required
+ memctl pointer to a memctl block or NULL
+
+Returns: pointer to memory or NULL on failure
+*/
+
+extern void *
+PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl)
+{
+pcre2_memctl *newmemctl;
+void *yield = (memctl == NULL)? malloc(size) :
+ memctl->malloc(size, memctl->memory_data);
+if (yield == NULL) return NULL;
+newmemctl = (pcre2_memctl *)yield;
+if (memctl == NULL)
+ {
+ newmemctl->malloc = default_malloc;
+ newmemctl->free = default_free;
+ newmemctl->memory_data = NULL;
+ }
+else *newmemctl = *memctl;
+return yield;
+}
+
+
+
+/*************************************************
+* Create and initialize contexts *
+*************************************************/
+
+/* Initializing for compile and match contexts is done in separate, private
+functions so that these can be called from functions such as pcre2_compile()
+when an external context is not supplied. The initializing functions have an
+option to set up default memory management. */
+
+PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
+pcre2_general_context_create(void *(*private_malloc)(size_t, void *),
+ void (*private_free)(void *, void *), void *memory_data)
+{
+pcre2_general_context *gcontext;
+if (private_malloc == NULL) private_malloc = default_malloc;
+if (private_free == NULL) private_free = default_free;
+gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);
+if (gcontext == NULL) return NULL;
+gcontext->memctl.malloc = private_malloc;
+gcontext->memctl.free = private_free;
+gcontext->memctl.memory_data = memory_data;
+return gcontext;
+}
+
+
+/* A default compile context is set up to save having to initialize at run time
+when no context is supplied to the compile function. */
+
+const pcre2_compile_context PRIV(default_compile_context) = {
+ { default_malloc, default_free, NULL }, /* Default memory handling */
+ NULL, /* Stack guard */
+ NULL, /* Stack guard data */
+ PRIV(default_tables), /* Character tables */
+ PCRE2_UNSET, /* Max pattern length */
+ BSR_DEFAULT, /* Backslash R default */
+ NEWLINE_DEFAULT, /* Newline convention */
+ PARENS_NEST_LIMIT }; /* As it says */
+
+/* The create function copies the default into the new memory, but must
+override the default memory handling functions if a gcontext was provided. */
+
+PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
+pcre2_compile_context_create(pcre2_general_context *gcontext)
+{
+pcre2_compile_context *ccontext = PRIV(memctl_malloc)(
+ sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext);
+if (ccontext == NULL) return NULL;
+*ccontext = PRIV(default_compile_context);
+if (gcontext != NULL)
+ *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
+return ccontext;
+}
+
+
+/* A default match context is set up to save having to initialize at run time
+when no context is supplied to a match function. */
+
+const pcre2_match_context PRIV(default_match_context) = {
+ { default_malloc, default_free, NULL },
+#ifdef HEAP_MATCH_RECURSE
+ { default_malloc, default_free, NULL },
+#endif
+#ifdef SUPPORT_JIT
+ NULL,
+ NULL,
+#endif
+ NULL,
+ NULL,
+ PCRE2_UNSET, /* Offset limit */
+ MATCH_LIMIT,
+ MATCH_LIMIT_RECURSION };
+
+/* The create function copies the default into the new memory, but must
+override the default memory handling functions if a gcontext was provided. */
+
+PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
+pcre2_match_context_create(pcre2_general_context *gcontext)
+{
+pcre2_match_context *mcontext = PRIV(memctl_malloc)(
+ sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext);
+if (mcontext == NULL) return NULL;
+*mcontext = PRIV(default_match_context);
+if (gcontext != NULL)
+ *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext);
+return mcontext;
+}
+
+
+/*************************************************
+* Context copy functions *
+*************************************************/
+
+PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
+pcre2_general_context_copy(pcre2_general_context *gcontext)
+{
+pcre2_general_context *new =
+ gcontext->memctl.malloc(sizeof(pcre2_real_general_context),
+ gcontext->memctl.memory_data);
+if (new == NULL) return NULL;
+memcpy(new, gcontext, sizeof(pcre2_real_general_context));
+return new;
+}
+
+
+PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
+pcre2_compile_context_copy(pcre2_compile_context *ccontext)
+{
+pcre2_compile_context *new =
+ ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),
+ ccontext->memctl.memory_data);
+if (new == NULL) return NULL;
+memcpy(new, ccontext, sizeof(pcre2_real_compile_context));
+return new;
+}
+
+
+PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
+pcre2_match_context_copy(pcre2_match_context *mcontext)
+{
+pcre2_match_context *new =
+ mcontext->memctl.malloc(sizeof(pcre2_real_match_context),
+ mcontext->memctl.memory_data);
+if (new == NULL) return NULL;
+memcpy(new, mcontext, sizeof(pcre2_real_match_context));
+return new;
+}
+
+
+
+/*************************************************
+* Context free functions *
+*************************************************/
+
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_general_context_free(pcre2_general_context *gcontext)
+{
+if (gcontext != NULL)
+ gcontext->memctl.free(gcontext, gcontext->memctl.memory_data);
+}
+
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_compile_context_free(pcre2_compile_context *ccontext)
+{
+if (ccontext != NULL)
+ ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
+}
+
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_match_context_free(pcre2_match_context *mcontext)
+{
+if (mcontext != NULL)
+ mcontext->memctl.free(mcontext, mcontext->memctl.memory_data);
+}
+
+
+
+
+/*************************************************
+* Set values in contexts *
+*************************************************/
+
+/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid
+data is given. Only some of the functions are able to test the validity of the
+data. */
+
+
+/* ------------ Compile contexts ------------ */
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_character_tables(pcre2_compile_context *ccontext,
+ const unsigned char *tables)
+{
+ccontext->tables = tables;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value)
+{
+switch(value)
+ {
+ case PCRE2_BSR_ANYCRLF:
+ case PCRE2_BSR_UNICODE:
+ ccontext->bsr_convention = value;
+ return 0;
+
+ default:
+ return PCRE2_ERROR_BADDATA;
+ }
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
+{
+ccontext->max_pattern_length = length;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)
+{
+switch(newline)
+ {
+ case PCRE2_NEWLINE_CR:
+ case PCRE2_NEWLINE_LF:
+ case PCRE2_NEWLINE_CRLF:
+ case PCRE2_NEWLINE_ANY:
+ case PCRE2_NEWLINE_ANYCRLF:
+ ccontext->newline_convention = newline;
+ return 0;
+
+ default:
+ return PCRE2_ERROR_BADDATA;
+ }
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)
+{
+ccontext->parens_nest_limit = limit;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
+ int (*guard)(uint32_t, void *), void *user_data)
+{
+ccontext->stack_guard = guard;
+ccontext->stack_guard_data = user_data;
+return 0;
+}
+
+
+/* ------------ Match contexts ------------ */
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_callout(pcre2_match_context *mcontext,
+ int (*callout)(pcre2_callout_block *, void *), void *callout_data)
+{
+mcontext->callout = callout;
+mcontext->callout_data = callout_data;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit)
+{
+mcontext->match_limit = limit;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)
+{
+mcontext->offset_limit = limit;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)
+{
+mcontext->recursion_limit = limit;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_recursion_memory_management(pcre2_match_context *mcontext,
+ void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),
+ void *mydata)
+{
+#ifdef HEAP_MATCH_RECURSE
+mcontext->stack_memctl.malloc = mymalloc;
+mcontext->stack_memctl.free = myfree;
+mcontext->stack_memctl.memory_data = mydata;
+#else
+(void)mcontext;
+(void)mymalloc;
+(void)myfree;
+(void)mydata;
+#endif
+return 0;
+}
+
+/* End of pcre2_context.c */
diff --git a/thirdparty/pcre2/src/pcre2_dfa_match.c b/thirdparty/pcre2/src/pcre2_dfa_match.c
new file mode 100644
index 0000000000..c909d61285
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_dfa_match.c
@@ -0,0 +1,3628 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre2_dfa_match(), which is an
+alternative matching function that uses a sort of DFA algorithm (not a true
+FSM). This is NOT Perl-compatible, but it has advantages in certain
+applications. */
+
+
+/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved
+the performance of his patterns greatly. I could not use it as it stood, as it
+was not thread safe, and made assumptions about pattern sizes. Also, it caused
+test 7 to loop, and test 9 to crash with a segfault.
+
+The issue is the check for duplicate states, which is done by a simple linear
+search up the state list. (Grep for "duplicate" below to find the code.) For
+many patterns, there will never be many states active at one time, so a simple
+linear search is fine. In patterns that have many active states, it might be a
+bottleneck. The suggested code used an indexing scheme to remember which states
+had previously been used for each character, and avoided the linear search when
+it knew there was no chance of a duplicate. This was implemented when adding
+states to the state lists.
+
+I wrote some thread-safe, not-limited code to try something similar at the time
+of checking for duplicates (instead of when adding states), using index vectors
+on the stack. It did give a 13% improvement with one specially constructed
+pattern for certain subject strings, but on other strings and on many of the
+simpler patterns in the test suite it did worse. The major problem, I think,
+was the extra time to initialize the index. This had to be done for each call
+of internal_dfa_match(). (The supplied patch used a static vector, initialized
+only once - I suspect this was the cause of the problems with the tests.)
+
+Overall, I concluded that the gains in some cases did not outweigh the losses
+in others, so I abandoned this code. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK mb /* Block containing newline information */
+#define PSSTART start_subject /* Field containing processed string start */
+#define PSEND end_subject /* Field containing processed string end */
+
+#include "pcre2_internal.h"
+
+#define PUBLIC_DFA_MATCH_OPTIONS \
+ (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
+ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
+ PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART)
+
+
+/*************************************************
+* Code parameters and static tables *
+*************************************************/
+
+/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes
+into others, under special conditions. A gap of 20 between the blocks should be
+enough. The resulting opcodes don't have to be less than 256 because they are
+never stored, so we push them well clear of the normal opcodes. */
+
+#define OP_PROP_EXTRA 300
+#define OP_EXTUNI_EXTRA 320
+#define OP_ANYNL_EXTRA 340
+#define OP_HSPACE_EXTRA 360
+#define OP_VSPACE_EXTRA 380
+
+
+/* This table identifies those opcodes that are followed immediately by a
+character that is to be tested in some way. This makes it possible to
+centralize the loading of these characters. In the case of Type * etc, the
+"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a
+small value. Non-zero values in the table are the offsets from the opcode where
+the character is to be found. ***NOTE*** If the start of this table is
+modified, the three tables that follow must also be modified. */
+
+static const uint8_t coptable[] = {
+ 0, /* End */
+ 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
+ 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
+ 0, 0, 0, /* Any, AllAny, Anybyte */
+ 0, 0, /* \P, \p */
+ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
+ 0, /* \X */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */
+ 1, /* Char */
+ 1, /* Chari */
+ 1, /* not */
+ 1, /* noti */
+ /* Positive single-char repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */
+ 1+IMM2_SIZE, /* exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */
+ 1+IMM2_SIZE, /* exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */
+ /* Negative single-char repeats - only for chars < 256 */
+ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */
+ 1+IMM2_SIZE, /* NOT exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */
+ 1+IMM2_SIZE, /* NOT exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */
+ /* Positive type repeats */
+ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */
+ 1+IMM2_SIZE, /* Type exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */
+ /* Character class & ref repeats */
+ 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
+ 0, 0, /* CRRANGE, CRMINRANGE */
+ 0, 0, 0, 0, /* Possessive *+, ++, ?+, CRPOSRANGE */
+ 0, /* CLASS */
+ 0, /* NCLASS */
+ 0, /* XCLASS - variable length */
+ 0, /* REF */
+ 0, /* REFI */
+ 0, /* DNREF */
+ 0, /* DNREFI */
+ 0, /* RECURSE */
+ 0, /* CALLOUT */
+ 0, /* CALLOUT_STR */
+ 0, /* Alt */
+ 0, /* Ket */
+ 0, /* KetRmax */
+ 0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
+ 0, /* Assert */
+ 0, /* Assert not */
+ 0, /* Assert behind */
+ 0, /* Assert behind not */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
+ 0, 0, /* CREF, DNCREF */
+ 0, 0, /* RREF, DNRREF */
+ 0, 0, /* FALSE, TRUE */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */
+};
+
+/* This table identifies those opcodes that inspect a character. It is used to
+remember the fact that a character could have been inspected when the end of
+the subject is reached. ***NOTE*** If the start of this table is modified, the
+two tables that follow must also be modified. */
+
+static const uint8_t poptable[] = {
+ 0, /* End */
+ 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
+ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
+ 1, 1, 1, /* Any, AllAny, Anybyte */
+ 1, 1, /* \P, \p */
+ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */
+ 1, /* \X */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */
+ 1, /* Char */
+ 1, /* Chari */
+ 1, /* not */
+ 1, /* noti */
+ /* Positive single-char repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* upto, minupto, exact */
+ 1, 1, 1, 1, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */
+ /* Negative single-char repeats - only for chars < 256 */
+ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* NOT upto, minupto, exact */
+ 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* NOT upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */
+ /* Positive type repeats */
+ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* Type upto, minupto, exact */
+ 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */
+ /* Character class & ref repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1, 1, /* CRRANGE, CRMINRANGE */
+ 1, 1, 1, 1, /* Possessive *+, ++, ?+, CRPOSRANGE */
+ 1, /* CLASS */
+ 1, /* NCLASS */
+ 1, /* XCLASS - variable length */
+ 0, /* REF */
+ 0, /* REFI */
+ 0, /* DNREF */
+ 0, /* DNREFI */
+ 0, /* RECURSE */
+ 0, /* CALLOUT */
+ 0, /* CALLOUT_STR */
+ 0, /* Alt */
+ 0, /* Ket */
+ 0, /* KetRmax */
+ 0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
+ 0, /* Assert */
+ 0, /* Assert not */
+ 0, /* Assert behind */
+ 0, /* Assert behind not */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
+ 0, 0, /* CREF, DNCREF */
+ 0, 0, /* RREF, DNRREF */
+ 0, 0, /* FALSE, TRUE */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */
+};
+
+/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
+and \w */
+
+static const uint8_t toptable1[] = {
+ 0, 0, 0, 0, 0, 0,
+ ctype_digit, ctype_digit,
+ ctype_space, ctype_space,
+ ctype_word, ctype_word,
+ 0, 0 /* OP_ANY, OP_ALLANY */
+};
+
+static const uint8_t toptable2[] = {
+ 0, 0, 0, 0, 0, 0,
+ ctype_digit, 0,
+ ctype_space, 0,
+ ctype_word, 0,
+ 1, 1 /* OP_ANY, OP_ALLANY */
+};
+
+
+/* Structure for holding data about a particular state, which is in effect the
+current data for an active path through the match tree. It must consist
+entirely of ints because the working vector we are passed, and which we put
+these structures in, is a vector of ints. */
+
+typedef struct stateblock {
+ int offset; /* Offset to opcode (-ve has meaning) */
+ int count; /* Count for repeats */
+ int data; /* Some use extra data */
+} stateblock;
+
+#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int))
+
+
+
+/*************************************************
+* Match a Regular Expression - DFA engine *
+*************************************************/
+
+/* This internal function applies a compiled pattern to a subject string,
+starting at a given point, using a DFA engine. This function is called from the
+external one, possibly multiple times if the pattern is not anchored. The
+function calls itself recursively for some kinds of subpattern.
+
+Arguments:
+ mb the match_data block with fixed information
+ this_start_code the opening bracket of this subexpression's code
+ current_subject where we currently are in the subject string
+ start_offset start offset in the subject string
+ offsets vector to contain the matching string offsets
+ offsetcount size of same
+ workspace vector of workspace
+ wscount size of same
+ rlevel function call recursion level
+
+Returns: > 0 => number of match offset pairs placed in offsets
+ = 0 => offsets overflowed; longest matches are present
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+
+The following macros are used for adding states to the two state vectors (one
+for the current character, one for the following character). */
+
+#define ADD_ACTIVE(x,y) \
+ if (active_count++ < wscount) \
+ { \
+ next_active_state->offset = (x); \
+ next_active_state->count = (y); \
+ next_active_state++; \
+ } \
+ else return PCRE2_ERROR_DFA_WSSIZE
+
+#define ADD_ACTIVE_DATA(x,y,z) \
+ if (active_count++ < wscount) \
+ { \
+ next_active_state->offset = (x); \
+ next_active_state->count = (y); \
+ next_active_state->data = (z); \
+ next_active_state++; \
+ } \
+ else return PCRE2_ERROR_DFA_WSSIZE
+
+#define ADD_NEW(x,y) \
+ if (new_count++ < wscount) \
+ { \
+ next_new_state->offset = (x); \
+ next_new_state->count = (y); \
+ next_new_state++; \
+ } \
+ else return PCRE2_ERROR_DFA_WSSIZE
+
+#define ADD_NEW_DATA(x,y,z) \
+ if (new_count++ < wscount) \
+ { \
+ next_new_state->offset = (x); \
+ next_new_state->count = (y); \
+ next_new_state->data = (z); \
+ next_new_state++; \
+ } \
+ else return PCRE2_ERROR_DFA_WSSIZE
+
+/* And now, here is the code */
+
+static int
+internal_dfa_match(
+ dfa_match_block *mb,
+ PCRE2_SPTR this_start_code,
+ PCRE2_SPTR current_subject,
+ PCRE2_SIZE start_offset,
+ PCRE2_SIZE *offsets,
+ uint32_t offsetcount,
+ int *workspace,
+ int wscount,
+ uint32_t rlevel)
+{
+stateblock *active_states, *new_states, *temp_states;
+stateblock *next_active_state, *next_new_state;
+
+const uint8_t *ctypes, *lcc, *fcc;
+PCRE2_SPTR ptr;
+PCRE2_SPTR end_code;
+PCRE2_SPTR first_op;
+
+dfa_recursion_info new_recursive;
+
+int active_count, new_count, match_count;
+
+/* Some fields in the mb block are frequently referenced, so we load them into
+independent variables in the hope that this will perform better. */
+
+PCRE2_SPTR start_subject = mb->start_subject;
+PCRE2_SPTR end_subject = mb->end_subject;
+PCRE2_SPTR start_code = mb->start_code;
+
+#ifdef SUPPORT_UNICODE
+BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
+#else
+BOOL utf = FALSE;
+#endif
+
+BOOL reset_could_continue = FALSE;
+
+if (rlevel++ > mb->match_limit_recursion) return PCRE2_ERROR_RECURSIONLIMIT;
+offsetcount &= (uint32_t)(-2); /* Round down */
+
+wscount -= 2;
+wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
+ (2 * INTS_PER_STATEBLOCK);
+
+ctypes = mb->tables + ctypes_offset;
+lcc = mb->tables + lcc_offset;
+fcc = mb->tables + fcc_offset;
+
+match_count = PCRE2_ERROR_NOMATCH; /* A negative number */
+
+active_states = (stateblock *)(workspace + 2);
+next_new_state = new_states = active_states + wscount;
+new_count = 0;
+
+first_op = this_start_code + 1 + LINK_SIZE +
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
+
+/* The first thing in any (sub) pattern is a bracket of some sort. Push all
+the alternative states onto the list, and find out where the end is. This
+makes is possible to use this function recursively, when we want to stop at a
+matching internal ket rather than at the end.
+
+If the first opcode in the first alternative is OP_REVERSE, we are dealing with
+a backward assertion. In that case, we have to find out the maximum amount to
+move back, and set up each alternative appropriately. */
+
+if (*first_op == OP_REVERSE)
+ {
+ size_t max_back = 0;
+ size_t gone_back;
+
+ end_code = this_start_code;
+ do
+ {
+ size_t back = (size_t)GET(end_code, 2+LINK_SIZE);
+ if (back > max_back) max_back = back;
+ end_code += GET(end_code, 1);
+ }
+ while (*end_code == OP_ALT);
+
+ /* If we can't go back the amount required for the longest lookbehind
+ pattern, go back as far as we can; some alternatives may still be viable. */
+
+#ifdef SUPPORT_UNICODE
+ /* In character mode we have to step back character by character */
+
+ if (utf)
+ {
+ for (gone_back = 0; gone_back < max_back; gone_back++)
+ {
+ if (current_subject <= start_subject) break;
+ current_subject--;
+ ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--);
+ }
+ }
+ else
+#endif
+
+ /* In byte-mode we can do this quickly. */
+
+ {
+ size_t current_offset = (size_t)(current_subject - start_subject);
+ gone_back = (current_offset < max_back)? current_offset : max_back;
+ current_subject -= gone_back;
+ }
+
+ /* Save the earliest consulted character */
+
+ if (current_subject < mb->start_used_ptr)
+ mb->start_used_ptr = current_subject;
+
+ /* Now we can process the individual branches. */
+
+ end_code = this_start_code;
+ do
+ {
+ size_t back = (size_t)GET(end_code, 2+LINK_SIZE);
+ if (back <= gone_back)
+ {
+ int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE);
+ ADD_NEW_DATA(-bstate, 0, (int)(gone_back - back));
+ }
+ end_code += GET(end_code, 1);
+ }
+ while (*end_code == OP_ALT);
+ }
+
+/* This is the code for a "normal" subpattern (not a backward assertion). The
+start of a whole pattern is always one of these. If we are at the top level,
+we may be asked to restart matching from the same point that we reached for a
+previous partial match. We still have to scan through the top-level branches to
+find the end state. */
+
+else
+ {
+ end_code = this_start_code;
+
+ /* Restarting */
+
+ if (rlevel == 1 && (mb->moptions & PCRE2_DFA_RESTART) != 0)
+ {
+ do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
+ new_count = workspace[1];
+ if (!workspace[0])
+ memcpy(new_states, active_states, (size_t)new_count * sizeof(stateblock));
+ }
+
+ /* Not restarting */
+
+ else
+ {
+ int length = 1 + LINK_SIZE +
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
+ do
+ {
+ ADD_NEW((int)(end_code - start_code + length), 0);
+ end_code += GET(end_code, 1);
+ length = 1 + LINK_SIZE;
+ }
+ while (*end_code == OP_ALT);
+ }
+ }
+
+workspace[0] = 0; /* Bit indicating which vector is current */
+
+/* Loop for scanning the subject */
+
+ptr = current_subject;
+for (;;)
+ {
+ int i, j;
+ int clen, dlen;
+ uint32_t c, d;
+ int forced_fail = 0;
+ BOOL partial_newline = FALSE;
+ BOOL could_continue = reset_could_continue;
+ reset_could_continue = FALSE;
+
+ if (ptr > mb->last_used_ptr) mb->last_used_ptr = ptr;
+
+ /* Make the new state list into the active state list and empty the
+ new state list. */
+
+ temp_states = active_states;
+ active_states = new_states;
+ new_states = temp_states;
+ active_count = new_count;
+ new_count = 0;
+
+ workspace[0] ^= 1; /* Remember for the restarting feature */
+ workspace[1] = active_count;
+
+ /* Set the pointers for adding new states */
+
+ next_active_state = active_states + active_count;
+ next_new_state = new_states;
+
+ /* Load the current character from the subject outside the loop, as many
+ different states may want to look at it, and we assume that at least one
+ will. */
+
+ if (ptr < end_subject)
+ {
+ clen = 1; /* Number of data items in the character */
+#ifdef SUPPORT_UNICODE
+ GETCHARLENTEST(c, ptr, clen);
+#else
+ c = *ptr;
+#endif /* SUPPORT_UNICODE */
+ }
+ else
+ {
+ clen = 0; /* This indicates the end of the subject */
+ c = NOTACHAR; /* This value should never actually be used */
+ }
+
+ /* Scan up the active states and act on each one. The result of an action
+ may be to add more states to the currently active list (e.g. on hitting a
+ parenthesis) or it may be to put states on the new list, for considering
+ when we move the character pointer on. */
+
+ for (i = 0; i < active_count; i++)
+ {
+ stateblock *current_state = active_states + i;
+ BOOL caseless = FALSE;
+ PCRE2_SPTR code;
+ uint32_t codevalue;
+ int state_offset = current_state->offset;
+ int rrc;
+ int count;
+
+ /* A negative offset is a special case meaning "hold off going to this
+ (negated) state until the number of characters in the data field have
+ been skipped". If the could_continue flag was passed over from a previous
+ state, arrange for it to passed on. */
+
+ if (state_offset < 0)
+ {
+ if (current_state->data > 0)
+ {
+ ADD_NEW_DATA(state_offset, current_state->count,
+ current_state->data - 1);
+ if (could_continue) reset_could_continue = TRUE;
+ continue;
+ }
+ else
+ {
+ current_state->offset = state_offset = -state_offset;
+ }
+ }
+
+ /* Check for a duplicate state with the same count, and skip if found.
+ See the note at the head of this module about the possibility of improving
+ performance here. */
+
+ for (j = 0; j < i; j++)
+ {
+ if (active_states[j].offset == state_offset &&
+ active_states[j].count == current_state->count)
+ goto NEXT_ACTIVE_STATE;
+ }
+
+ /* The state offset is the offset to the opcode */
+
+ code = start_code + state_offset;
+ codevalue = *code;
+
+ /* If this opcode inspects a character, but we are at the end of the
+ subject, remember the fact for use when testing for a partial match. */
+
+ if (clen == 0 && poptable[codevalue] != 0)
+ could_continue = TRUE;
+
+ /* If this opcode is followed by an inline character, load it. It is
+ tempting to test for the presence of a subject character here, but that
+ is wrong, because sometimes zero repetitions of the subject are
+ permitted.
+
+ We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
+ argument that is not a data character - but is always one byte long because
+ the values are small. We have to take special action to deal with \P, \p,
+ \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert
+ these ones to new opcodes. */
+
+ if (coptable[codevalue] > 0)
+ {
+ dlen = 1;
+#ifdef SUPPORT_UNICODE
+ if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
+#endif /* SUPPORT_UNICODE */
+ d = code[coptable[codevalue]];
+ if (codevalue >= OP_TYPESTAR)
+ {
+ switch(d)
+ {
+ case OP_ANYBYTE: return PCRE2_ERROR_DFA_UITEM;
+ case OP_NOTPROP:
+ case OP_PROP: codevalue += OP_PROP_EXTRA; break;
+ case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
+ case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;
+ case OP_NOT_HSPACE:
+ case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;
+ case OP_NOT_VSPACE:
+ case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;
+ default: break;
+ }
+ }
+ }
+ else
+ {
+ dlen = 0; /* Not strictly necessary, but compilers moan */
+ d = NOTACHAR; /* if these variables are not set. */
+ }
+
+
+ /* Now process the individual opcodes */
+
+ switch (codevalue)
+ {
+/* ========================================================================== */
+ /* These cases are never obeyed. This is a fudge that causes a compile-
+ time error if the vectors coptable or poptable, which are indexed by
+ opcode, are not the correct length. It seems to be the only way to do
+ such a check at compile time, as the sizeof() operator does not work
+ in the C preprocessor. */
+
+ case OP_TABLE_LENGTH:
+ case OP_TABLE_LENGTH +
+ ((sizeof(coptable) == OP_TABLE_LENGTH) &&
+ (sizeof(poptable) == OP_TABLE_LENGTH)):
+ break;
+
+/* ========================================================================== */
+ /* Reached a closing bracket. If not at the end of the pattern, carry
+ on with the next opcode. For repeating opcodes, also add the repeat
+ state. Note that KETRPOS will always be encountered at the end of the
+ subpattern, because the possessive subpattern repeats are always handled
+ using recursive calls. Thus, it never adds any new states.
+
+ At the end of the (sub)pattern, unless we have an empty string and
+ PCRE2_NOTEMPTY is set, or PCRE2_NOTEMPTY_ATSTART is set and we are at the
+ start of the subject, save the match data, shifting up all previous
+ matches so we always have the longest first. */
+
+ case OP_KET:
+ case OP_KETRMIN:
+ case OP_KETRMAX:
+ case OP_KETRPOS:
+ if (code != end_code)
+ {
+ ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
+ if (codevalue != OP_KET)
+ {
+ ADD_ACTIVE(state_offset - (int)GET(code, 1), 0);
+ }
+ }
+ else
+ {
+ if (ptr > current_subject ||
+ ((mb->moptions & PCRE2_NOTEMPTY) == 0 &&
+ ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) == 0 ||
+ current_subject > start_subject + mb->start_offset)))
+ {
+ if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
+ else if (match_count > 0 && ++match_count * 2 > (int)offsetcount)
+ match_count = 0;
+ count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2;
+ if (count > 0) memmove(offsets + 2, offsets,
+ (size_t)count * sizeof(PCRE2_SIZE));
+ if (offsetcount >= 2)
+ {
+ offsets[0] = (PCRE2_SIZE)(current_subject - start_subject);
+ offsets[1] = (PCRE2_SIZE)(ptr - start_subject);
+ }
+ if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count;
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These opcodes add to the current list of states without looking
+ at the current character. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_ALT:
+ do { code += GET(code, 1); } while (*code == OP_ALT);
+ ADD_ACTIVE((int)(code - start_code), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRA:
+ case OP_SBRA:
+ do
+ {
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ code += GET(code, 1);
+ }
+ while (*code == OP_ALT);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CBRA:
+ case OP_SCBRA:
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0);
+ code += GET(code, 1);
+ while (*code == OP_ALT)
+ {
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ code += GET(code, 1);
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ ADD_ACTIVE(state_offset + 1, 0);
+ code += 1 + GET(code, 2);
+ while (*code == OP_ALT) code += GET(code, 1);
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SKIPZERO:
+ code += 1 + GET(code, 2);
+ while (*code == OP_ALT) code += GET(code, 1);
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CIRC:
+ if (ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0)
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CIRCM:
+ if ((ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) ||
+ ((ptr != end_subject || (mb->poptions & PCRE2_ALT_CIRCUMFLEX) != 0 )
+ && WAS_NEWLINE(ptr)))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EOD:
+ if (ptr >= end_subject)
+ {
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SOD:
+ if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SOM:
+ if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+
+/* ========================================================================== */
+ /* These opcodes inspect the next subject character, and sometimes
+ the previous one as well, but do not have an argument. The variable
+ clen contains the length of the current character and is zero if we are
+ at the end of the subject. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANY:
+ if (clen > 0 && !IS_NEWLINE(ptr))
+ {
+ if (ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else
+ {
+ ADD_NEW(state_offset + 1, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_ALLANY:
+ if (clen > 0)
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EODN:
+ if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_DOLL:
+ if ((mb->moptions & PCRE2_NOTEOL) == 0)
+ {
+ if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 ||
+ ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
+ (ptr == end_subject - mb->nllen)
+ ))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ else if (ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ {
+ reset_could_continue = TRUE;
+ ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+ }
+ else could_continue = partial_newline = TRUE;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_DOLLM:
+ if ((mb->moptions & PCRE2_NOTEOL) == 0)
+ {
+ if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 ||
+ ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ else if (ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ {
+ reset_could_continue = TRUE;
+ ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+ }
+ else could_continue = partial_newline = TRUE;
+ }
+ }
+ else if (IS_NEWLINE(ptr))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+
+ case OP_DIGIT:
+ case OP_WHITESPACE:
+ case OP_WORDCHAR:
+ if (clen > 0 && c < 256 &&
+ ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ if (clen > 0 && (c >= 256 ||
+ ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ {
+ int left_word, right_word;
+
+ if (ptr > start_subject)
+ {
+ PCRE2_SPTR temp = ptr - 1;
+ if (temp < mb->start_used_ptr) mb->start_used_ptr = temp;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (utf) { BACKCHAR(temp); }
+#endif
+ GETCHARTEST(d, temp);
+#ifdef SUPPORT_UNICODE
+ if ((mb->poptions & PCRE2_UCP) != 0)
+ {
+ if (d == '_') left_word = TRUE; else
+ {
+ uint32_t cat = UCD_CATEGORY(d);
+ left_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
+ }
+ else left_word = FALSE;
+
+ if (clen > 0)
+ {
+ if (ptr >= mb->last_used_ptr)
+ {
+ PCRE2_SPTR temp = ptr + 1;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (utf) { FORWARDCHARTEST(temp, mb->end_subject); }
+#endif
+ mb->last_used_ptr = temp;
+ }
+#ifdef SUPPORT_UNICODE
+ if ((mb->poptions & PCRE2_UCP) != 0)
+ {
+ if (c == '_') right_word = TRUE; else
+ {
+ uint32_t cat = UCD_CATEGORY(c);
+ right_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
+ }
+ else right_word = FALSE;
+
+ if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+
+ /*-----------------------------------------------------------------*/
+ /* Check the next character by Unicode property. We will get here only
+ if the support is in the binary; otherwise a compile-time error occurs.
+ */
+
+#ifdef SUPPORT_UNICODE
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (clen > 0)
+ {
+ BOOL OK;
+ const uint32_t *cp;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[1])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[2];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[2];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[2];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ case PT_CLIST:
+ cp = PRIV(ucd_caseless_sets) + code[2];
+ for (;;)
+ {
+ if (c < *cp) { OK = FALSE; break; }
+ if (c == *cp++) { OK = TRUE; break; }
+ }
+ break;
+
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }
+ }
+ break;
+#endif
+
+
+
+/* ========================================================================== */
+ /* These opcodes likewise inspect the subject character, but have an
+ argument that is not a data character. It is one of these opcodes:
+ OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,
+ OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (count > 0 && codevalue == OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + 2, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEEXACT:
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These are virtual opcodes that are used when something like
+ OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its
+ argument. It keeps the code above fast for the other cases. The argument
+ is in the d variable. */
+
+#ifdef SUPPORT_UNICODE
+ case OP_PROP_EXTRA + OP_TYPEPLUS:
+ case OP_PROP_EXTRA + OP_TYPEMINPLUS:
+ case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ const uint32_t *cp;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[2])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[3];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[3];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ case PT_CLIST:
+ cp = PRIV(ucd_caseless_sets) + code[3];
+ for (;;)
+ {
+ if (c < *cp) { OK = FALSE; break; }
+ if (c == *cp++) { OK = TRUE; break; }
+ }
+ break;
+
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEPLUS:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ uint32_t lgb, rgb;
+ PCRE2_SPTR nptr = ptr + clen;
+ int ncount = 0;
+ if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ lgb = UCD_GRAPHBREAK(c);
+ while (nptr < end_subject)
+ {
+ dlen = 1;
+ if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
+ rgb = UCD_GRAPHBREAK(d);
+ if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
+ ncount++;
+ lgb = rgb;
+ nptr += dlen;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEPLUS:
+ case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
+ goto ANYNL01;
+
+ case CHAR_CR:
+ if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
+ /* Fall through */
+
+ ANYNL01:
+ case CHAR_LF:
+ if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, ncount);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEPLUS:
+ case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_VSPACE))
+ {
+ if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEPLUS:
+ case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ HSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UNICODE
+ case OP_PROP_EXTRA + OP_TYPEQUERY:
+ case OP_PROP_EXTRA + OP_TYPEMINQUERY:
+ case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
+ count = 4;
+ goto QS1;
+
+ case OP_PROP_EXTRA + OP_TYPESTAR:
+ case OP_PROP_EXTRA + OP_TYPEMINSTAR:
+ case OP_PROP_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS1:
+
+ ADD_ACTIVE(state_offset + 4, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ const uint32_t *cp;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[2])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[3];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[3];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ case PT_CLIST:
+ cp = PRIV(ucd_caseless_sets) + code[3];
+ for (;;)
+ {
+ if (c < *cp) { OK = FALSE; break; }
+ if (c == *cp++) { OK = TRUE; break; }
+ }
+ break;
+
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEQUERY:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS2;
+
+ case OP_EXTUNI_EXTRA + OP_TYPESTAR:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS2:
+
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ uint32_t lgb, rgb;
+ PCRE2_SPTR nptr = ptr + clen;
+ int ncount = 0;
+ if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ lgb = UCD_GRAPHBREAK(c);
+ while (nptr < end_subject)
+ {
+ dlen = 1;
+ if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
+ rgb = UCD_GRAPHBREAK(d);
+ if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
+ ncount++;
+ lgb = rgb;
+ nptr += dlen;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEQUERY:
+ case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS3;
+
+ case OP_ANYNL_EXTRA + OP_TYPESTAR:
+ case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS3:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
+ goto ANYNL02;
+
+ case CHAR_CR:
+ if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
+ /* Fall through */
+
+ ANYNL02:
+ case CHAR_LF:
+ if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEQUERY:
+ case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS4;
+
+ case OP_VSPACE_EXTRA + OP_TYPESTAR:
+ case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS4:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+ if (OK == (d == OP_VSPACE))
+ {
+ if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEQUERY:
+ case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS5;
+
+ case OP_HSPACE_EXTRA + OP_TYPESTAR:
+ case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS5:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ HSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UNICODE
+ case OP_PROP_EXTRA + OP_TYPEEXACT:
+ case OP_PROP_EXTRA + OP_TYPEUPTO:
+ case OP_PROP_EXTRA + OP_TYPEMINUPTO:
+ case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ const uint32_t *cp;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[1 + IMM2_SIZE + 1])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[1 + IMM2_SIZE + 2];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[1 + IMM2_SIZE + 2];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ case PT_CLIST:
+ cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
+ for (;;)
+ {
+ if (c < *cp) { OK = FALSE; break; }
+ if (c == *cp++) { OK = TRUE; break; }
+ }
+ break;
+
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEEXACT:
+ case OP_EXTUNI_EXTRA + OP_TYPEUPTO:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ uint32_t lgb, rgb;
+ PCRE2_SPTR nptr = ptr + clen;
+ int ncount = 0;
+ if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ lgb = UCD_GRAPHBREAK(c);
+ while (nptr < end_subject)
+ {
+ dlen = 1;
+ if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
+ rgb = UCD_GRAPHBREAK(d);
+ if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
+ ncount++;
+ lgb = rgb;
+ nptr += dlen;
+ }
+ if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ reset_could_continue = TRUE;
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, ncount); }
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEEXACT:
+ case OP_ANYNL_EXTRA + OP_TYPEUPTO:
+ case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
+ goto ANYNL03;
+
+ case CHAR_CR:
+ if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
+ /* Fall through */
+
+ ANYNL03:
+ case CHAR_LF:
+ if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, ncount); }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEEXACT:
+ case OP_VSPACE_EXTRA + OP_TYPEUPTO:
+ case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ }
+
+ if (OK == (d == OP_VSPACE))
+ {
+ if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, 0); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEEXACT:
+ case OP_HSPACE_EXTRA + OP_TYPEUPTO:
+ case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ HSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, 0); }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These opcodes are followed by a character that is usually compared
+ to the current subject character; it is loaded into d. We still get
+ here even if there is no subject character, because in some cases zero
+ repetitions are permitted. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_CHAR:
+ if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CHARI:
+ if (clen == 0) break;
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
+ {
+ unsigned int othercase;
+ if (c < 128)
+ othercase = fcc[c];
+ else
+ othercase = UCD_OTHERCASE(c);
+ if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+ /* Not UTF mode */
+ {
+ if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
+ { ADD_NEW(state_offset + 2, 0); }
+ }
+ break;
+
+
+#ifdef SUPPORT_UNICODE
+ /*-----------------------------------------------------------------*/
+ /* This is a tricky one because it can match more than one character.
+ Find out how many characters to skip, and then set up a negative state
+ to wait for them to pass before continuing. */
+
+ case OP_EXTUNI:
+ if (clen > 0)
+ {
+ uint32_t lgb, rgb;
+ PCRE2_SPTR nptr = ptr + clen;
+ int ncount = 0;
+ lgb = UCD_GRAPHBREAK(c);
+ while (nptr < end_subject)
+ {
+ dlen = 1;
+ if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
+ rgb = UCD_GRAPHBREAK(d);
+ if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
+ ncount++;
+ lgb = rgb;
+ nptr += dlen;
+ }
+ if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ reset_could_continue = TRUE;
+ ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ /* This is a tricky like EXTUNI because it too can match more than one
+ character (when CR is followed by LF). In this case, set up a negative
+ state to wait for one character to pass before continuing. */
+
+ case OP_ANYNL:
+ if (clen > 0) switch(c)
+ {
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
+
+ case CHAR_LF:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+
+ case CHAR_CR:
+ if (ptr + 1 >= end_subject)
+ {
+ ADD_NEW(state_offset + 1, 0);
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ reset_could_continue = TRUE;
+ }
+ else if (UCHAR21TEST(ptr + 1) == CHAR_LF)
+ {
+ ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+ }
+ else
+ {
+ ADD_NEW(state_offset + 1, 0);
+ }
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_VSPACE:
+ if (clen > 0) switch(c)
+ {
+ VSPACE_CASES:
+ break;
+
+ default:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE:
+ if (clen > 0) switch(c)
+ {
+ VSPACE_CASES:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_HSPACE:
+ if (clen > 0) switch(c)
+ {
+ HSPACE_CASES:
+ break;
+
+ default:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE:
+ if (clen > 0) switch(c)
+ {
+ HSPACE_CASES:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ /* Match a negated single character casefully. */
+
+ case OP_NOT:
+ if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ /* Match a negated single character caselessly. */
+
+ case OP_NOTI:
+ if (clen > 0)
+ {
+ unsigned int otherd;
+#ifdef SUPPORT_UNICODE
+ if (utf && d >= 128)
+ otherd = UCD_OTHERCASE(d);
+ else
+#endif /* SUPPORT_UNICODE */
+ otherd = TABLE_GET(d, fcc, d);
+ if (c != d && c != otherd)
+ { ADD_NEW(state_offset + dlen + 1, 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUSI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+
+ /* Fall through */
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
+ if (clen > 0)
+ {
+ uint32_t otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf && d >= 128)
+ otherd = UCD_OTHERCASE(d);
+ else
+#endif /* SUPPORT_UNICODE */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (count > 0 &&
+ (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSQUERYI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSQUERY:
+ ADD_ACTIVE(state_offset + dlen + 1, 0);
+ if (clen > 0)
+ {
+ uint32_t otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf && d >= 128)
+ otherd = UCD_OTHERCASE(d);
+ else
+#endif /* SUPPORT_UNICODE */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + dlen + 1, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPOSSTARI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPOSSTAR:
+ ADD_ACTIVE(state_offset + dlen + 1, 0);
+ if (clen > 0)
+ {
+ uint32_t otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf && d >= 128)
+ otherd = UCD_OTHERCASE(d);
+ else
+#endif /* SUPPORT_UNICODE */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXACTI:
+ case OP_NOTEXACTI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_EXACT:
+ case OP_NOTEXACT:
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ uint32_t otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf && d >= 128)
+ otherd = UCD_OTHERCASE(d);
+ else
+#endif /* SUPPORT_UNICODE */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPOSUPTOI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTPOSUPTO:
+ ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ uint32_t otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf && d >= 128)
+ otherd = UCD_OTHERCASE(d);
+ else
+#endif /* SUPPORT_UNICODE */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= (int)GET2(code, 1))
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+
+/* ========================================================================== */
+ /* These are the class-handling opcodes */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_XCLASS:
+ {
+ BOOL isinclass = FALSE;
+ int next_state_offset;
+ PCRE2_SPTR ecode;
+
+ /* For a simple class, there is always just a 32-byte table, and we
+ can set isinclass from it. */
+
+ if (codevalue != OP_XCLASS)
+ {
+ ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR));
+ if (clen > 0)
+ {
+ isinclass = (c > 255)? (codevalue == OP_NCLASS) :
+ ((((uint8_t *)(code + 1))[c/8] & (1 << (c&7))) != 0);
+ }
+ }
+
+ /* An extended class may have a table or a list of single characters,
+ ranges, or both, and it may be positive or negative. There's a
+ function that sorts all this out. */
+
+ else
+ {
+ ecode = code + GET(code, 1);
+ if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);
+ }
+
+ /* At this point, isinclass is set for all kinds of class, and ecode
+ points to the byte after the end of the class. If there is a
+ quantifier, this is where it will be. */
+
+ next_state_offset = (int)(ecode - start_code);
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPOSSTAR:
+ ADD_ACTIVE(next_state_offset + 1, 0);
+ if (isinclass)
+ {
+ if (*ecode == OP_CRPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
+ if (isinclass)
+ {
+ if (count > 0 && *ecode == OP_CRPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ break;
+
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSQUERY:
+ ADD_ACTIVE(next_state_offset + 1, 0);
+ if (isinclass)
+ {
+ if (*ecode == OP_CRPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(next_state_offset + 1, 0);
+ }
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ count = current_state->count; /* Already matched */
+ if (count >= (int)GET2(ecode, 1))
+ { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
+ if (isinclass)
+ {
+ int max = (int)GET2(ecode, 1 + IMM2_SIZE);
+ if (*ecode == OP_CRPOSRANGE)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= max && max != 0) /* Max 0 => no limit */
+ { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ break;
+
+ default:
+ if (isinclass) { ADD_NEW(next_state_offset, 0); }
+ break;
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These are the opcodes for fancy brackets of various kinds. We have
+ to use recursion in order to handle them. The "always failing" assertion
+ (?!) is optimised to OP_FAIL when compiling, so we have to support that,
+ though the other "backtracking verbs" are not supported. */
+
+ case OP_FAIL:
+ forced_fail++; /* Count FAILs for multiple states */
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ {
+ PCRE2_SPTR endasscode = code + GET(code, 1);
+ PCRE2_SIZE local_offsets[2];
+ int rc;
+ int local_workspace[1000];
+
+ while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+ rc = internal_dfa_match(
+ mb, /* static match data */
+ code, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
+ if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
+ { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_COND:
+ case OP_SCOND:
+ {
+ PCRE2_SIZE local_offsets[1000];
+ int local_workspace[1000];
+ int codelink = (int)GET(code, 1);
+ PCRE2_UCHAR condcode;
+
+ /* Because of the way auto-callout works during compile, a callout item
+ is inserted between OP_COND and an assertion condition. This does not
+ happen for the other conditions. */
+
+ if (code[LINK_SIZE + 1] == OP_CALLOUT
+ || code[LINK_SIZE + 1] == OP_CALLOUT_STR)
+ {
+ PCRE2_SIZE callout_length = (code[LINK_SIZE + 1] == OP_CALLOUT)?
+ (PCRE2_SIZE)PRIV(OP_lengths)[OP_CALLOUT] :
+ (PCRE2_SIZE)GET(code, 2 + 3*LINK_SIZE);
+
+ rrc = 0;
+ if (mb->callout != NULL)
+ {
+ pcre2_callout_block cb;
+ cb.version = 1;
+ cb.capture_top = 1;
+ cb.capture_last = 0;
+ cb.offset_vector = offsets;
+ cb.mark = NULL; /* No (*MARK) support */
+ cb.subject = start_subject;
+ cb.subject_length = (PCRE2_SIZE)(end_subject - start_subject);
+ cb.start_match = (PCRE2_SIZE)(current_subject - start_subject);
+ cb.current_position = (PCRE2_SIZE)(ptr - start_subject);
+ cb.pattern_position = GET(code, LINK_SIZE + 2);
+ cb.next_item_length = GET(code, LINK_SIZE + 2 + LINK_SIZE);
+
+ if (code[LINK_SIZE + 1] == OP_CALLOUT)
+ {
+ cb.callout_number = code[2 + 3*LINK_SIZE];
+ cb.callout_string_offset = 0;
+ cb.callout_string = NULL;
+ cb.callout_string_length = 0;
+ }
+ else
+ {
+ cb.callout_number = 0;
+ cb.callout_string_offset = GET(code, 2 + 4*LINK_SIZE);
+ cb.callout_string = code + (2 + 5*LINK_SIZE) + 1;
+ cb.callout_string_length =
+ callout_length - (1 + 4*LINK_SIZE) - 2;
+ }
+
+ if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0)
+ return rrc; /* Abandon */
+ }
+ if (rrc > 0) break; /* Fail this thread */
+ code += callout_length; /* Skip callout data */
+ }
+
+ condcode = code[LINK_SIZE+1];
+
+ /* Back reference conditions and duplicate named recursion conditions
+ are not supported */
+
+ if (condcode == OP_CREF || condcode == OP_DNCREF ||
+ condcode == OP_DNRREF)
+ return PCRE2_ERROR_DFA_UCOND;
+
+ /* The DEFINE condition is always false, and the assertion (?!) is
+ converted to OP_FAIL. */
+
+ if (condcode == OP_FALSE || condcode == OP_FAIL)
+ { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+
+ /* There is also an always-true condition */
+
+ else if (condcode == OP_TRUE)
+ { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
+
+ /* The only supported version of OP_RREF is for the value RREF_ANY,
+ which means "test if in any recursion". We can't test for specifically
+ recursed groups. */
+
+ else if (condcode == OP_RREF)
+ {
+ unsigned int value = GET2(code, LINK_SIZE + 2);
+ if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND;
+ if (mb->recursive != NULL)
+ { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
+ else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+ }
+
+ /* Otherwise, the condition is an assertion */
+
+ else
+ {
+ int rc;
+ PCRE2_SPTR asscode = code + LINK_SIZE + 1;
+ PCRE2_SPTR endasscode = asscode + GET(asscode, 1);
+
+ while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+ rc = internal_dfa_match(
+ mb, /* fixed match data */
+ asscode, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
+ if ((rc >= 0) ==
+ (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
+ { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
+ else
+ { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_RECURSE:
+ {
+ dfa_recursion_info *ri;
+ PCRE2_SIZE local_offsets[1000];
+ int local_workspace[1000];
+ PCRE2_SPTR callpat = start_code + GET(code, 1);
+ uint32_t recno = (callpat == mb->start_code)? 0 :
+ GET2(callpat, 1 + LINK_SIZE);
+ int rc;
+
+ /* Check for repeating a recursion without advancing the subject
+ pointer. This should catch convoluted mutual recursions. (Some simple
+ cases are caught at compile time.) */
+
+ for (ri = mb->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && ptr == ri->subject_position)
+ return PCRE2_ERROR_RECURSELOOP;
+
+ /* Remember this recursion and where we started it so as to
+ catch infinite loops. */
+
+ new_recursive.group_num = recno;
+ new_recursive.subject_position = ptr;
+ new_recursive.prevrec = mb->recursive;
+ mb->recursive = &new_recursive;
+
+ rc = internal_dfa_match(
+ mb, /* fixed match data */
+ callpat, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ mb->recursive = new_recursive.prevrec; /* Done this recursion */
+
+ /* Ran out of internal offsets */
+
+ if (rc == 0) return PCRE2_ERROR_DFA_RECURSE;
+
+ /* For each successful matched substring, set up the next state with a
+ count of characters to skip before trying it. Note that the count is in
+ characters, not bytes. */
+
+ if (rc > 0)
+ {
+ for (rc = rc*2 - 2; rc >= 0; rc -= 2)
+ {
+ PCRE2_SIZE charcount = local_offsets[rc+1] - local_offsets[rc];
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (utf)
+ {
+ PCRE2_SPTR p = start_subject + local_offsets[rc];
+ PCRE2_SPTR pp = start_subject + local_offsets[rc+1];
+ while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
+ }
+#endif
+ if (charcount > 0)
+ {
+ ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0,
+ (int)(charcount - 1));
+ }
+ else
+ {
+ ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);
+ }
+ }
+ }
+ else if (rc != PCRE2_ERROR_NOMATCH) return rc;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ {
+ PCRE2_SIZE charcount, matched_count;
+ PCRE2_SPTR local_ptr = ptr;
+ BOOL allow_zero;
+
+ if (codevalue == OP_BRAPOSZERO)
+ {
+ allow_zero = TRUE;
+ codevalue = *(++code); /* Codevalue will be one of above BRAs */
+ }
+ else allow_zero = FALSE;
+
+ /* Loop to match the subpattern as many times as possible as if it were
+ a complete pattern. */
+
+ for (matched_count = 0;; matched_count++)
+ {
+ PCRE2_SIZE local_offsets[2];
+ int local_workspace[1000];
+
+ int rc = internal_dfa_match(
+ mb, /* fixed match data */
+ code, /* this subexpression's code */
+ local_ptr, /* where we currently are */
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ /* Failed to match */
+
+ if (rc < 0)
+ {
+ if (rc != PCRE2_ERROR_NOMATCH) return rc;
+ break;
+ }
+
+ /* Matched: break the loop if zero characters matched. */
+
+ charcount = local_offsets[1] - local_offsets[0];
+ if (charcount == 0) break;
+ local_ptr += charcount; /* Advance temporary position ptr */
+ }
+
+ /* At this point we have matched the subpattern matched_count
+ times, and local_ptr is pointing to the character after the end of the
+ last match. */
+
+ if (matched_count > 0 || allow_zero)
+ {
+ PCRE2_SPTR end_subpattern = code;
+ int next_state_offset;
+
+ do { end_subpattern += GET(end_subpattern, 1); }
+ while (*end_subpattern == OP_ALT);
+ next_state_offset =
+ (int)(end_subpattern - start_code + LINK_SIZE + 1);
+
+ /* Optimization: if there are no more active states, and there
+ are no new states yet set up, then skip over the subject string
+ right here, to save looping. Otherwise, set up the new state to swing
+ into action when the end of the matched substring is reached. */
+
+ if (i + 1 >= active_count && new_count == 0)
+ {
+ ptr = local_ptr;
+ clen = 0;
+ ADD_NEW(next_state_offset, 0);
+ }
+ else
+ {
+ PCRE2_SPTR p = ptr;
+ PCRE2_SPTR pp = local_ptr;
+ charcount = (PCRE2_SIZE)(pp - p);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
+#endif
+ ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));
+ }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ {
+ PCRE2_SIZE local_offsets[2];
+ int local_workspace[1000];
+
+ int rc = internal_dfa_match(
+ mb, /* fixed match data */
+ code, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc >= 0)
+ {
+ PCRE2_SPTR end_subpattern = code;
+ PCRE2_SIZE charcount = local_offsets[1] - local_offsets[0];
+ int next_state_offset, repeat_state_offset;
+
+ do { end_subpattern += GET(end_subpattern, 1); }
+ while (*end_subpattern == OP_ALT);
+ next_state_offset =
+ (int)(end_subpattern - start_code + LINK_SIZE + 1);
+
+ /* If the end of this subpattern is KETRMAX or KETRMIN, we must
+ arrange for the repeat state also to be added to the relevant list.
+ Calculate the offset, or set -1 for no repeat. */
+
+ repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
+ *end_subpattern == OP_KETRMIN)?
+ (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;
+
+ /* If we have matched an empty string, add the next state at the
+ current character pointer. This is important so that the duplicate
+ checking kicks in, which is what breaks infinite loops that match an
+ empty string. */
+
+ if (charcount == 0)
+ {
+ ADD_ACTIVE(next_state_offset, 0);
+ }
+
+ /* Optimization: if there are no more active states, and there
+ are no new states yet set up, then skip over the subject string
+ right here, to save looping. Otherwise, set up the new state to swing
+ into action when the end of the matched substring is reached. */
+
+ else if (i + 1 >= active_count && new_count == 0)
+ {
+ ptr += charcount;
+ clen = 0;
+ ADD_NEW(next_state_offset, 0);
+
+ /* If we are adding a repeat state at the new character position,
+ we must fudge things so that it is the only current state.
+ Otherwise, it might be a duplicate of one we processed before, and
+ that would cause it to be skipped. */
+
+ if (repeat_state_offset >= 0)
+ {
+ next_active_state = active_states;
+ active_count = 0;
+ i = -1;
+ ADD_ACTIVE(repeat_state_offset, 0);
+ }
+ }
+ else
+ {
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (utf)
+ {
+ PCRE2_SPTR p = start_subject + local_offsets[0];
+ PCRE2_SPTR pp = start_subject + local_offsets[1];
+ while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
+ }
+#endif
+ ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));
+ if (repeat_state_offset >= 0)
+ { ADD_NEW_DATA(-repeat_state_offset, 0, (int)(charcount - 1)); }
+ }
+ }
+ else if (rc != PCRE2_ERROR_NOMATCH) return rc;
+ }
+ break;
+
+
+/* ========================================================================== */
+ /* Handle callouts */
+
+ case OP_CALLOUT:
+ case OP_CALLOUT_STR:
+ {
+ unsigned int callout_length = (*code == OP_CALLOUT)
+ ? PRIV(OP_lengths)[OP_CALLOUT] : GET(code, 1 + 2*LINK_SIZE);
+ rrc = 0;
+
+ if (mb->callout != NULL)
+ {
+ pcre2_callout_block cb;
+ cb.version = 1;
+ cb.capture_top = 1;
+ cb.capture_last = 0;
+ cb.offset_vector = offsets;
+ cb.mark = NULL; /* No (*MARK) support */
+ cb.subject = start_subject;
+ cb.subject_length = (PCRE2_SIZE)(end_subject - start_subject);
+ cb.start_match = (PCRE2_SIZE)(current_subject - start_subject);
+ cb.current_position = (PCRE2_SIZE)(ptr - start_subject);
+ cb.pattern_position = GET(code, 1);
+ cb.next_item_length = GET(code, 1 + LINK_SIZE);
+
+ if (*code == OP_CALLOUT)
+ {
+ cb.callout_number = code[1 + 2*LINK_SIZE];
+ cb.callout_string_offset = 0;
+ cb.callout_string = NULL;
+ cb.callout_string_length = 0;
+ }
+ else
+ {
+ cb.callout_number = 0;
+ cb.callout_string_offset = GET(code, 1 + 3*LINK_SIZE);
+ cb.callout_string = code + (1 + 4*LINK_SIZE) + 1;
+ cb.callout_string_length =
+ callout_length - (1 + 4*LINK_SIZE) - 2;
+ }
+
+ if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0)
+ return rrc; /* Abandon */
+ }
+ if (rrc == 0)
+ { ADD_ACTIVE(state_offset + (int)callout_length, 0); }
+ }
+ break;
+
+
+/* ========================================================================== */
+ default: /* Unsupported opcode */
+ return PCRE2_ERROR_DFA_UITEM;
+ }
+
+ NEXT_ACTIVE_STATE: continue;
+
+ } /* End of loop scanning active states */
+
+ /* We have finished the processing at the current subject character. If no
+ new states have been set for the next character, we have found all the
+ matches that we are going to find. If we are at the top level and partial
+ matching has been requested, check for appropriate conditions.
+
+ The "forced_ fail" variable counts the number of (*F) encountered for the
+ character. If it is equal to the original active_count (saved in
+ workspace[1]) it means that (*F) was found on every active state. In this
+ case we don't want to give a partial match.
+
+ The "could_continue" variable is true if a state could have continued but
+ for the fact that the end of the subject was reached. */
+
+ if (new_count <= 0)
+ {
+ if (rlevel == 1 && /* Top level, and */
+ could_continue && /* Some could go on, and */
+ forced_fail != workspace[1] && /* Not all forced fail & */
+ ( /* either... */
+ (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */
+ || /* or... */
+ ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */
+ match_count < 0) /* no matches */
+ ) && /* And... */
+ (
+ partial_newline || /* Either partial NL */
+ ( /* or ... */
+ ptr >= end_subject && /* End of subject and */
+ ptr > mb->start_used_ptr) /* Inspected non-empty string */
+ )
+ )
+ match_count = PCRE2_ERROR_PARTIAL;
+ break; /* In effect, "return", but see the comment below */
+ }
+
+ /* One or more states are active for the next character. */
+
+ ptr += clen; /* Advance to next subject character */
+ } /* Loop to move along the subject string */
+
+/* Control gets here from "break" a few lines above. We do it this way because
+if we use "return" above, we have compiler trouble. Some compilers warn if
+there's nothing here because they think the function doesn't return a value. On
+the other hand, if we put a dummy statement here, some more clever compilers
+complain that it can't be reached. Sigh. */
+
+return match_count;
+}
+
+
+
+/*************************************************
+* Match a pattern using the DFA algorithm *
+*************************************************/
+
+/* This function matches a compiled pattern to a subject string, using the
+alternate matching algorithm that finds all matches at once.
+
+Arguments:
+ code points to the compiled pattern
+ subject subject string
+ length length of subject string
+ startoffset where to start matching in the subject
+ options option bits
+ match_data points to a match data structure
+ gcontext points to a match context
+ workspace pointer to workspace
+ wscount size of workspace
+
+Returns: > 0 => number of match offset pairs placed in offsets
+ = 0 => offsets overflowed; longest matches are present
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
+ PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
+ pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount)
+{
+const pcre2_real_code *re = (const pcre2_real_code *)code;
+
+PCRE2_SPTR start_match;
+PCRE2_SPTR end_subject;
+PCRE2_SPTR bumpalong_limit;
+PCRE2_SPTR req_cu_ptr;
+
+BOOL utf, anchored, startline, firstline;
+
+BOOL has_first_cu = FALSE;
+BOOL has_req_cu = FALSE;
+PCRE2_UCHAR first_cu = 0;
+PCRE2_UCHAR first_cu2 = 0;
+PCRE2_UCHAR req_cu = 0;
+PCRE2_UCHAR req_cu2 = 0;
+
+const uint8_t *start_bits = NULL;
+
+/* We need to have mb pointing to a match block, because the IS_NEWLINE macro
+is used below, and it expects NLBLOCK to be defined as a pointer. */
+
+dfa_match_block actual_match_block;
+dfa_match_block *mb = &actual_match_block;
+
+/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated
+subject string. */
+
+if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject);
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
+if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL)
+ return PCRE2_ERROR_NULL;
+if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE;
+if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE2_ERROR_BADMAGIC. */
+
+if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+
+/* Check the code unit width. */
+
+if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
+ return PCRE2_ERROR_BADMODE;
+
+/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
+options variable for this function. Users of PCRE2 who are not calling the
+function directly would like to have a way of setting these flags, in the same
+way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with
+constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and
+(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be
+transferred to the options for this function. The bits are guaranteed to be
+adjacent, but do not have the same values. This bit of Boolean trickery assumes
+that the match-time bits are not more significant than the flag bits. If by
+accident this is not the case, a compile-time division by zero error will
+occur. */
+
+#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)
+#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)
+options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
+#undef FF
+#undef OO
+
+/* If restarting after a partial match, do some sanity checks on the contents
+of the workspace. */
+
+if ((options & PCRE2_DFA_RESTART) != 0)
+ {
+ if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
+ workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))
+ return PCRE2_ERROR_DFA_BADRESTART;
+ }
+
+/* Set some local values */
+
+utf = (re->overall_options & PCRE2_UTF) != 0;
+start_match = subject + start_offset;
+end_subject = subject + length;
+req_cu_ptr = start_match - 1;
+anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 ||
+ (re->overall_options & PCRE2_ANCHORED) != 0;
+
+/* The "must be at the start of a line" flags are used in a loop when finding
+where to start. */
+
+startline = (re->flags & PCRE2_STARTLINE) != 0;
+firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
+bumpalong_limit = end_subject;
+
+/* Get data from the match context, if present, and fill in the fields in the
+match block. It is an error to set an offset limit without setting the flag at
+compile time. */
+
+if (mcontext == NULL)
+ {
+ mb->callout = NULL;
+ mb->memctl = re->memctl;
+ mb->match_limit_recursion = PRIV(default_match_context).recursion_limit;
+ }
+else
+ {
+ if (mcontext->offset_limit != PCRE2_UNSET)
+ {
+ if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
+ return PCRE2_ERROR_BADOFFSETLIMIT;
+ bumpalong_limit = subject + mcontext->offset_limit;
+ }
+ mb->callout = mcontext->callout;
+ mb->callout_data = mcontext->callout_data;
+ mb->memctl = mcontext->memctl;
+ mb->match_limit_recursion = mcontext->recursion_limit;
+ }
+if (mb->match_limit_recursion > re->limit_recursion)
+ mb->match_limit_recursion = re->limit_recursion;
+
+mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
+ re->name_count * re->name_entry_size;
+mb->tables = re->tables;
+mb->start_subject = subject;
+mb->end_subject = end_subject;
+mb->start_offset = start_offset;
+mb->moptions = options;
+mb->poptions = re->overall_options;
+
+/* Process the \R and newline settings. */
+
+mb->bsr_convention = re->bsr_convention;
+mb->nltype = NLTYPE_FIXED;
+switch(re->newline_convention)
+ {
+ case PCRE2_NEWLINE_CR:
+ mb->nllen = 1;
+ mb->nl[0] = CHAR_CR;
+ break;
+
+ case PCRE2_NEWLINE_LF:
+ mb->nllen = 1;
+ mb->nl[0] = CHAR_NL;
+ break;
+
+ case PCRE2_NEWLINE_CRLF:
+ mb->nllen = 2;
+ mb->nl[0] = CHAR_CR;
+ mb->nl[1] = CHAR_NL;
+ break;
+
+ case PCRE2_NEWLINE_ANY:
+ mb->nltype = NLTYPE_ANY;
+ break;
+
+ case PCRE2_NEWLINE_ANYCRLF:
+ mb->nltype = NLTYPE_ANYCRLF;
+ break;
+
+ default: return PCRE2_ERROR_INTERNAL;
+ }
+
+/* Check a UTF string for validity if required. For 8-bit and 16-bit strings,
+we must also check that a starting offset does not point into the middle of a
+multiunit character. We check only the portion of the subject that is going to
+be inspected during matching - from the offset minus the maximum back reference
+to the given length. This saves time when a small part of a large subject is
+being matched by the use of a starting offset. Note that the maximum lookbehind
+is a number of characters, not code units. */
+
+#ifdef SUPPORT_UNICODE
+if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
+ {
+ PCRE2_SPTR check_subject = start_match; /* start_match includes offset */
+
+ if (start_offset > 0)
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ unsigned int i;
+ if (start_match < end_subject && NOT_FIRSTCU(*start_match))
+ return PCRE2_ERROR_BADUTFOFFSET;
+ for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)
+ {
+ check_subject--;
+ while (check_subject > subject &&
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ (*check_subject & 0xc0) == 0x80)
+#else /* 16-bit */
+ (*check_subject & 0xfc00) == 0xdc00)
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ check_subject--;
+ }
+#else /* In the 32-bit library, one code unit equals one character. */
+ check_subject -= re->max_lookbehind;
+ if (check_subject < subject) check_subject = subject;
+#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
+ }
+
+ /* Validate the relevant portion of the subject. After an error, adjust the
+ offset to be an absolute offset in the whole string. */
+
+ match_data->rc = PRIV(valid_utf)(check_subject,
+ length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar));
+ if (match_data->rc != 0)
+ {
+ match_data->startchar += (PCRE2_SIZE)(check_subject - subject);
+ return match_data->rc;
+ }
+ }
+#endif /* SUPPORT_UNICODE */
+
+/* Set up the first code unit to match, if available. The first_codeunit value
+is never set for an anchored regular expression, but the anchoring may be
+forced at run time, so we have to test for anchoring. The first code unit may
+be unset for an unanchored pattern, of course. If there's no first code unit
+there may be a bitmap of possible first characters. */
+
+if (!anchored)
+ {
+ if ((re->flags & PCRE2_FIRSTSET) != 0)
+ {
+ has_first_cu = TRUE;
+ first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
+ if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
+ {
+ first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ if (utf && first_cu > 127)
+ first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
+#endif
+ }
+ }
+ else
+ if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
+ start_bits = re->start_bitmap;
+ }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE2_LASTSET) != 0)
+ {
+ has_req_cu = TRUE;
+ req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);
+ if ((re->flags & PCRE2_LASTCASELESS) != 0)
+ {
+ req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ if (utf && req_cu > 127) req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
+#endif
+ }
+ }
+
+/* Fill in fields that are always returned in the match data. */
+
+match_data->code = re;
+match_data->subject = subject;
+match_data->mark = NULL;
+match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER;
+
+/* Call the main matching function, looping for a non-anchored regex after a
+failed match. If not restarting, perform certain optimizations at the start of
+a match. */
+
+for (;;)
+ {
+ int rc;
+
+ /* ----------------- Start of match optimizations ---------------- */
+
+ /* There are some optimizations that avoid running the match if a known
+ starting point is not found, or if a known later code unit is not present.
+ However, there is an option (settable at compile time) that disables
+ these, for testing and for ensuring that all callouts do actually occur.
+ The optimizations must also be avoided when restarting a DFA match. */
+
+ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 &&
+ (options & PCRE2_DFA_RESTART) == 0)
+ {
+ PCRE2_SPTR save_end_subject = end_subject;
+
+ /* If firstline is TRUE, the start of the match is constrained to the first
+ line of a multiline string. That is, the match must be before or at the
+ first newline. Implement this by temporarily adjusting end_subject so that
+ we stop the optimization scans at a newline. If the match fails at the
+ newline, later code breaks this loop. */
+
+ if (firstline)
+ {
+ PCRE2_SPTR t = start_match;
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ while (t < mb->end_subject && !IS_NEWLINE(t))
+ {
+ t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
+ }
+ }
+ else
+#endif
+ while (t < mb->end_subject && !IS_NEWLINE(t)) t++;
+ end_subject = t;
+ }
+
+ /* Advance to a unique first code unit if there is one. */
+
+ if (has_first_cu)
+ {
+ PCRE2_UCHAR smc;
+ if (first_cu != first_cu2)
+ while (start_match < end_subject &&
+ (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2)
+ start_match++;
+ else
+ while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu)
+ start_match++;
+ }
+
+ /* Or to just after a linebreak for a multiline match */
+
+ else if (startline)
+ {
+ if (start_match > mb->start_subject + start_offset)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ {
+ start_match++;
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
+ }
+ }
+ else
+#endif
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ start_match++;
+
+ /* If we have just passed a CR and the newline option is ANY or
+ ANYCRLF, and we are now at a LF, advance the match position by one more
+ code unit. */
+
+ if (start_match[-1] == CHAR_CR &&
+ (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
+ start_match < end_subject &&
+ UCHAR21TEST(start_match) == CHAR_NL)
+ start_match++;
+ }
+ }
+
+ /* Or to a non-unique first code unit if any have been identified. The
+ bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all
+ code units greater than 254 set the 255 bit. */
+
+ else if (start_bits != NULL)
+ {
+ while (start_match < end_subject)
+ {
+ uint32_t c = UCHAR21TEST(start_match);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ if (c > 255) c = 255;
+#endif
+ if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
+ start_match++;
+ }
+ }
+
+ /* Restore fudged end_subject */
+
+ end_subject = save_end_subject;
+
+ /* The following two optimizations are disabled for partial matching. */
+
+ if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0)
+ {
+ /* The minimum matching length is a lower bound; no actual string of that
+ length may actually match the pattern. Although the value is, strictly,
+ in characters, we treat it as code units to avoid spending too much time
+ in this optimization. */
+
+ if (end_subject - start_match < re->minlength) return PCRE2_ERROR_NOMATCH;
+
+ /* If req_cu is set, we know that that code unit must appear in the
+ subject for the match to succeed. If the first code unit is set, req_cu
+ must be later in the subject; otherwise the test starts at the match
+ point. This optimization can save a huge amount of backtracking in
+ patterns with nested unlimited repeats that aren't going to match.
+ Writing separate code for cased/caseless versions makes it go faster, as
+ does using an autoincrement and backing off on a match.
+
+ HOWEVER: when the subject string is very, very long, searching to its end
+ can take a long time, and give bad performance on quite ordinary
+ patterns. This showed up when somebody was matching something like
+ /^\d+C/ on a 32-megabyte string... so we don't do this when the string is
+ sufficiently long. */
+
+ if (has_req_cu && end_subject - start_match < REQ_CU_MAX)
+ {
+ PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
+
+ /* We don't need to repeat the search if we haven't yet reached the
+ place we found it at last time. */
+
+ if (p > req_cu_ptr)
+ {
+ if (req_cu != req_cu2)
+ {
+ while (p < end_subject)
+ {
+ uint32_t pp = UCHAR21INCTEST(p);
+ if (pp == req_cu || pp == req_cu2) { p--; break; }
+ }
+ }
+ else
+ {
+ while (p < end_subject)
+ {
+ if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
+ }
+ }
+
+ /* If we can't find the required code unit, break the matching loop,
+ forcing a match failure. */
+
+ if (p >= end_subject) break;
+
+ /* If we have found the required code unit, save the point where we
+ found it, so that we don't search again next time round the loop if
+ the start hasn't passed this code unit yet. */
+
+ req_cu_ptr = p;
+ }
+ }
+ }
+ }
+
+ /* ------------ End of start of match optimizations ------------ */
+
+ /* Give no match if we have passed the bumpalong limit. */
+
+ if (start_match > bumpalong_limit) break;
+
+ /* OK, now we can do the business */
+
+ mb->start_used_ptr = start_match;
+ mb->last_used_ptr = start_match;
+ mb->recursive = NULL;
+
+ rc = internal_dfa_match(
+ mb, /* fixed match data */
+ mb->start_code, /* this subexpression's code */
+ start_match, /* where we currently are */
+ start_offset, /* start offset in subject */
+ match_data->ovector, /* offset vector */
+ (uint32_t)match_data->oveccount * 2, /* actual size of same */
+ workspace, /* workspace vector */
+ (int)wscount, /* size of same */
+ 0); /* function recurse level */
+
+ /* Anything other than "no match" means we are done, always; otherwise, carry
+ on only if not anchored. */
+
+ if (rc != PCRE2_ERROR_NOMATCH || anchored)
+ {
+ if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0)
+ {
+ match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);
+ match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);
+ }
+ match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
+ match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject);
+ match_data->startchar = (PCRE2_SIZE)(start_match - subject);
+ match_data->rc = rc;
+ return rc;
+ }
+
+ /* Advance to the next subject character unless we are at the end of a line
+ and firstline is set. */
+
+ if (firstline && IS_NEWLINE(start_match)) break;
+ start_match++;
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
+ }
+#endif
+ if (start_match > end_subject) break;
+
+ /* If we have just passed a CR and we are now at a LF, and the pattern does
+ not contain any explicit matches for \r or \n, and the newline option is CRLF
+ or ANY or ANYCRLF, advance the match position by one more character. */
+
+ if (UCHAR21TEST(start_match - 1) == CHAR_CR &&
+ start_match < end_subject &&
+ UCHAR21TEST(start_match) == CHAR_NL &&
+ (re->flags & PCRE2_HASCRORLF) == 0 &&
+ (mb->nltype == NLTYPE_ANY ||
+ mb->nltype == NLTYPE_ANYCRLF ||
+ mb->nllen == 2))
+ start_match++;
+
+ } /* "Bumpalong" loop */
+
+
+return PCRE2_ERROR_NOMATCH;
+}
+
+/* End of pcre2_dfa_match.c */
diff --git a/thirdparty/pcre2/src/pcre2_error.c b/thirdparty/pcre2/src/pcre2_error.c
new file mode 100644
index 0000000000..437bdfd202
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_error.c
@@ -0,0 +1,325 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+#define STRING(a) # a
+#define XSTRING(s) STRING(s)
+
+/* The texts of compile-time error messages. Compile-time error numbers start
+at COMPILE_ERROR_BASE (100).
+
+This used to be a table of strings, but in order to reduce the number of
+relocations needed when a shared library is loaded dynamically, it is now one
+long string. We cannot use a table of offsets, because the lengths of inserts
+such as XSTRING(MAX_NAME_SIZE) are not known. Instead,
+pcre2_get_error_message() counts through to the one it wants - this isn't a
+performance issue because these strings are used only when there is an error.
+
+Each substring ends with \0 to insert a null character. This includes the final
+substring, so that the whole string ends with \0\0, which can be detected when
+counting through. */
+
+static const unsigned char compile_error_texts[] =
+ "no error\0"
+ "\\ at end of pattern\0"
+ "\\c at end of pattern\0"
+ "unrecognized character follows \\\0"
+ "numbers out of order in {} quantifier\0"
+ /* 5 */
+ "number too big in {} quantifier\0"
+ "missing terminating ] for character class\0"
+ "invalid escape sequence in character class\0"
+ "range out of order in character class\0"
+ "quantifier does not follow a repeatable item\0"
+ /* 10 */
+ "internal error: unexpected repeat\0"
+ "unrecognized character after (? or (?-\0"
+ "POSIX named classes are supported only within a class\0"
+ "POSIX collating elements are not supported\0"
+ "missing closing parenthesis\0"
+ /* 15 */
+ "reference to non-existent subpattern\0"
+ "pattern passed as NULL\0"
+ "unrecognised compile-time option bit(s)\0"
+ "missing ) after (?# comment\0"
+ "parentheses are too deeply nested\0"
+ /* 20 */
+ "regular expression is too large\0"
+ "failed to allocate heap memory\0"
+ "unmatched closing parenthesis\0"
+ "internal error: code overflow\0"
+ "missing closing parenthesis for condition\0"
+ /* 25 */
+ "lookbehind assertion is not fixed length\0"
+ "a relative value of zero is not allowed\0"
+ "conditional group contains more than two branches\0"
+ "assertion expected after (?( or (?(?C)\0"
+ "digit expected after (?+ or (?-\0"
+ /* 30 */
+ "unknown POSIX class name\0"
+ "internal error in pcre2_study(): should not occur\0"
+ "this version of PCRE2 does not have Unicode support\0"
+ "parentheses are too deeply nested (stack check)\0"
+ "character code point value in \\x{} or \\o{} is too large\0"
+ /* 35 */
+ "lookbehind is too complicated\0"
+ "\\C is not allowed in a lookbehind assertion in UTF-" XSTRING(PCRE2_CODE_UNIT_WIDTH) " mode\0"
+ "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0"
+ "number after (?C is greater than 255\0"
+ "closing parenthesis for (?C expected\0"
+ /* 40 */
+ "invalid escape sequence in (*VERB) name\0"
+ "unrecognized character after (?P\0"
+ "syntax error in subpattern name (missing terminator)\0"
+ "two named subpatterns have the same name (PCRE2_DUPNAMES not set)\0"
+ "group name must start with a non-digit\0"
+ /* 45 */
+ "this version of PCRE2 does not have support for \\P, \\p, or \\X\0"
+ "malformed \\P or \\p sequence\0"
+ "unknown property name after \\P or \\p\0"
+ "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0"
+ "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
+ /* 50 */
+ "invalid range in character class\0"
+ "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"
+ "internal error: overran compiling workspace\0"
+ "internal error: previously-checked referenced subpattern not found\0"
+ "DEFINE group contains more than one branch\0"
+ /* 55 */
+ "missing opening brace after \\o\0"
+ "internal error: unknown newline setting\0"
+ "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
+ "(?R (recursive pattern call) must be followed by a closing parenthesis\0"
+ "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
+ /* 60 */
+ "(*VERB) not recognized or malformed\0"
+ "group number is too big\0"
+ "subpattern name expected\0"
+ "internal error: parsed pattern overflow\0"
+ "non-octal character in \\o{} (closing brace missing?)\0"
+ /* 65 */
+ "different names for subpatterns of the same number are not allowed\0"
+ "(*MARK) must have an argument\0"
+ "non-hex character in \\x{} (closing brace missing?)\0"
+#ifndef EBCDIC
+ "\\c must be followed by a printable ASCII character\0"
+#else
+ "\\c must be followed by a letter or one of [\\]^_?\0"
+#endif
+ "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
+ /* 70 */
+ "internal error: unknown meta code in check_lookbehinds()\0"
+ "\\N is not supported in a class\0"
+ "callout string is too long\0"
+ "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
+ "using UTF is disabled by the application\0"
+ /* 75 */
+ "using UCP is disabled by the application\0"
+ "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"
+ "character code point value in \\u.... sequence is too large\0"
+ "digits missing in \\x{} or \\o{}\0"
+ "syntax error or number too big in (?(VERSION condition\0"
+ /* 80 */
+ "internal error: unknown opcode in auto_possessify()\0"
+ "missing terminating delimiter for callout with string argument\0"
+ "unrecognized string delimiter follows (?C\0"
+ "using \\C is disabled by the application\0"
+ "(?| and/or (?J: or (?x: parentheses are too deeply nested\0"
+ /* 85 */
+ "using \\C is disabled in this PCRE2 library\0"
+ "regular expression is too complicated\0"
+ "lookbehind assertion is too long\0"
+ "pattern string is longer than the limit set by the application\0"
+ "internal error: unknown code in parsed pattern\0"
+ /* 90 */
+ "internal error: bad code value in parsed_skip()\0"
+ ;
+
+/* Match-time and UTF error texts are in the same format. */
+
+static const unsigned char match_error_texts[] =
+ "no error\0"
+ "no match\0"
+ "partial match\0"
+ "UTF-8 error: 1 byte missing at end\0"
+ "UTF-8 error: 2 bytes missing at end\0"
+ /* 5 */
+ "UTF-8 error: 3 bytes missing at end\0"
+ "UTF-8 error: 4 bytes missing at end\0"
+ "UTF-8 error: 5 bytes missing at end\0"
+ "UTF-8 error: byte 2 top bits not 0x80\0"
+ "UTF-8 error: byte 3 top bits not 0x80\0"
+ /* 10 */
+ "UTF-8 error: byte 4 top bits not 0x80\0"
+ "UTF-8 error: byte 5 top bits not 0x80\0"
+ "UTF-8 error: byte 6 top bits not 0x80\0"
+ "UTF-8 error: 5-byte character is not allowed (RFC 3629)\0"
+ "UTF-8 error: 6-byte character is not allowed (RFC 3629)\0"
+ /* 15 */
+ "UTF-8 error: code points greater than 0x10ffff are not defined\0"
+ "UTF-8 error: code points 0xd800-0xdfff are not defined\0"
+ "UTF-8 error: overlong 2-byte sequence\0"
+ "UTF-8 error: overlong 3-byte sequence\0"
+ "UTF-8 error: overlong 4-byte sequence\0"
+ /* 20 */
+ "UTF-8 error: overlong 5-byte sequence\0"
+ "UTF-8 error: overlong 6-byte sequence\0"
+ "UTF-8 error: isolated byte with 0x80 bit set\0"
+ "UTF-8 error: illegal byte (0xfe or 0xff)\0"
+ "UTF-16 error: missing low surrogate at end\0"
+ /* 25 */
+ "UTF-16 error: invalid low surrogate\0"
+ "UTF-16 error: isolated low surrogate\0"
+ "UTF-32 error: code points 0xd800-0xdfff are not defined\0"
+ "UTF-32 error: code points greater than 0x10ffff are not defined\0"
+ "bad data value\0"
+ /* 30 */
+ "patterns do not all use the same character tables\0"
+ "magic number missing\0"
+ "pattern compiled in wrong mode: 8/16/32-bit error\0"
+ "bad offset value\0"
+ "bad option value\0"
+ /* 35 */
+ "invalid replacement string\0"
+ "bad offset into UTF string\0"
+ "callout error code\0" /* Never returned by PCRE2 itself */
+ "invalid data in workspace for DFA restart\0"
+ "too much recursion for DFA matching\0"
+ /* 40 */
+ "backreference condition or recursion test is not supported for DFA matching\0"
+ "function is not supported for DFA matching\0"
+ "pattern contains an item that is not supported for DFA matching\0"
+ "workspace size exceeded in DFA matching\0"
+ "internal error - pattern overwritten?\0"
+ /* 45 */
+ "bad JIT option\0"
+ "JIT stack limit reached\0"
+ "match limit exceeded\0"
+ "no more memory\0"
+ "unknown substring\0"
+ /* 50 */
+ "non-unique substring name\0"
+ "NULL argument passed\0"
+ "nested recursion at the same subject position\0"
+ "recursion limit exceeded\0"
+ "requested value is not available\0"
+ /* 55 */
+ "requested value is not set\0"
+ "offset limit set without PCRE2_USE_OFFSET_LIMIT\0"
+ "bad escape sequence in replacement string\0"
+ "expected closing curly bracket in replacement string\0"
+ "bad substitution in replacement string\0"
+ /* 60 */
+ "match with end before start is not supported\0"
+ "too many replacements (more than INT_MAX)\0"
+ "bad serialized data\0"
+ ;
+
+
+/*************************************************
+* Return error message *
+*************************************************/
+
+/* This function copies an error message into a buffer whose units are of an
+appropriate width. Error numbers are positive for compile-time errors, and
+negative for match-time errors (except for UTF errors), but the numbers are all
+distinct.
+
+Arguments:
+ enumber error number
+ buffer where to put the message (zero terminated)
+ size size of the buffer
+
+Returns: length of message if all is well
+ negative on error
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, PCRE2_SIZE size)
+{
+const unsigned char *message;
+PCRE2_SIZE i;
+int n;
+
+if (size == 0) return PCRE2_ERROR_NOMEMORY;
+
+if (enumber >= COMPILE_ERROR_BASE) /* Compile error */
+ {
+ message = compile_error_texts;
+ n = enumber - COMPILE_ERROR_BASE;
+ }
+else if (enumber < 0) /* Match or UTF error */
+ {
+ message = match_error_texts;
+ n = -enumber;
+ }
+else /* Invalid error number */
+ {
+ message = (unsigned char *)"\0"; /* Empty message list */
+ n = 1;
+ }
+
+for (; n > 0; n--)
+ {
+ while (*message++ != CHAR_NULL) {};
+ if (*message == CHAR_NULL) return PCRE2_ERROR_BADDATA;
+ }
+
+for (i = 0; *message != 0; i++)
+ {
+ if (i >= size - 1)
+ {
+ buffer[i] = 0; /* Terminate partial message */
+ return PCRE2_ERROR_NOMEMORY;
+ }
+ buffer[i] = *message++;
+ }
+
+buffer[i] = 0;
+return (int)i;
+}
+
+/* End of pcre2_error.c */
diff --git a/thirdparty/pcre2/src/pcre2_find_bracket.c b/thirdparty/pcre2/src/pcre2_find_bracket.c
new file mode 100644
index 0000000000..357385a11c
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_find_bracket.c
@@ -0,0 +1,218 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains a single function that scans through a compiled pattern
+until it finds a capturing bracket with the given number, or, if the number is
+negative, an instance of OP_REVERSE for a lookbehind. The function is called
+from pcre2_compile.c and also from pcre2_study.c when finding the minimum
+matching length. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+/*************************************************
+* Scan compiled regex for specific bracket *
+*************************************************/
+
+/*
+Arguments:
+ code points to start of expression
+ utf TRUE in UTF mode
+ number the required bracket number or negative to find a lookbehind
+
+Returns: pointer to the opcode for the bracket, or NULL if not found
+*/
+
+PCRE2_SPTR
+PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number)
+{
+for (;;)
+ {
+ PCRE2_UCHAR c = *code;
+
+ if (c == OP_END) return NULL;
+
+ /* XCLASS is used for classes that cannot be represented just by a bit map.
+ This includes negated single high-valued characters. CALLOUT_STR is used for
+ callouts with string arguments. In both cases the length in the table is
+ zero; the actual length is stored in the compiled code. */
+
+ if (c == OP_XCLASS) code += GET(code, 1);
+ else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);
+
+ /* Handle lookbehind */
+
+ else if (c == OP_REVERSE)
+ {
+ if (number < 0) return (PCRE2_UCHAR *)code;
+ code += PRIV(OP_lengths)[c];
+ }
+
+ /* Handle capturing bracket */
+
+ else if (c == OP_CBRA || c == OP_SCBRA ||
+ c == OP_CBRAPOS || c == OP_SCBRAPOS)
+ {
+ int n = (int)GET2(code, 1+LINK_SIZE);
+ if (n == number) return (PCRE2_UCHAR *)code;
+ code += PRIV(OP_lengths)[c];
+ }
+
+ /* Otherwise, we can get the item's length from the table, except that for
+ repeated character types, we have to test for \p and \P, which have an extra
+ two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
+ must add in its length. */
+
+ else
+ {
+ switch(c)
+ {
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
+ code += 2;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ code += PRIV(OP_lengths)[c];
+
+ /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be
+ followed by a multi-byte character. The length in the table is a minimum, so
+ we have to arrange to skip the extra bytes. */
+
+#ifdef MAYBE_UTF_MULTI
+ if (utf) switch(c)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif /* MAYBE_UTF_MULTI */
+ }
+ }
+}
+
+/* End of pcre2_find_bracket.c */
diff --git a/thirdparty/pcre2/src/pcre2_internal.h b/thirdparty/pcre2/src/pcre2_internal.h
new file mode 100644
index 0000000000..6a8774ce8c
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_internal.h
@@ -0,0 +1,1940 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE2 is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* We do not support both EBCDIC and Unicode at the same time. The "configure"
+script prevents both being selected, but not everybody uses "configure". EBCDIC
+is only supported for the 8-bit library, but the check for this has to be later
+in this file, because the first part is not width-dependent, and is included by
+pcre2test.c with CODE_UNIT_WIDTH == 0. */
+
+#if defined EBCDIC && defined SUPPORT_UNICODE
+#error The use of both EBCDIC and SUPPORT_UNICODE is not supported.
+#endif
+
+/* Standard C headers */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Macros to make boolean values more obvious. The #ifndef is to pacify
+compiler warnings in environments where these macros are defined elsewhere.
+Unfortunately, there is no way to do the same for the typedef. */
+
+typedef int BOOL;
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+/* Valgrind (memcheck) support */
+
+#ifdef SUPPORT_VALGRIND
+#include <valgrind/memcheck.h>
+#endif
+
+/* Older versions of MSVC lack snprintf(). This define allows for
+warning/error-free compilation and testing with MSVC compilers back to at least
+MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */
+
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+#define snprintf _snprintf
+#endif
+
+/* When compiling a DLL for Windows, the exported symbols have to be declared
+using some MS magic. I found some useful information on this web page:
+http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
+information there, using __declspec(dllexport) without "extern" we have a
+definition; with "extern" we have a declaration. The settings here override the
+setting in pcre2.h (which is included below); it defines only PCRE2_EXP_DECL,
+which is all that is needed for applications (they just import the symbols). We
+use:
+
+ PCRE2_EXP_DECL for declarations
+ PCRE2_EXP_DEFN for definitions
+
+The reason for wrapping this in #ifndef PCRE2_EXP_DECL is so that pcre2test,
+which is an application, but needs to import this file in order to "peek" at
+internals, can #include pcre2.h first to get an application's-eye view.
+
+In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
+special-purpose environments) might want to stick other stuff in front of
+exported symbols. That's why, in the non-Windows case, we set PCRE2_EXP_DEFN
+only if it is not already set. */
+
+#ifndef PCRE2_EXP_DECL
+# ifdef _WIN32
+# ifndef PCRE2_STATIC
+# define PCRE2_EXP_DECL extern __declspec(dllexport)
+# define PCRE2_EXP_DEFN __declspec(dllexport)
+# else
+# define PCRE2_EXP_DECL extern
+# define PCRE2_EXP_DEFN
+# endif
+# else
+# ifdef __cplusplus
+# define PCRE2_EXP_DECL extern "C"
+# else
+# define PCRE2_EXP_DECL extern
+# endif
+# ifndef PCRE2_EXP_DEFN
+# define PCRE2_EXP_DEFN PCRE2_EXP_DECL
+# endif
+# endif
+#endif
+
+/* Include the public PCRE2 header and the definitions of UCP character
+property values. This must follow the setting of PCRE2_EXP_DECL above. */
+
+#include "pcre2.h"
+#include "pcre2_ucp.h"
+
+/* When PCRE2 is compiled as a C++ library, the subject pointer can be replaced
+with a custom type. This makes it possible, for example, to allow pcre2_match()
+to process subject strings that are discontinuous by using a smart pointer
+class. It must always be possible to inspect all of the subject string in
+pcre2_match() because of the way it backtracks. */
+
+/* WARNING: This is as yet untested for PCRE2. */
+
+#ifdef CUSTOM_SUBJECT_PTR
+#undef PCRE2_SPTR
+#define PCRE2_SPTR CUSTOM_SUBJECT_PTR
+#endif
+
+/* When checking for integer overflow in pcre2_compile(), we need to handle
+large integers. If a 64-bit integer type is available, we can use that.
+Otherwise we have to cast to double, which of course requires floating point
+arithmetic. Handle this by defining a macro for the appropriate type. If
+stdint.h is available, include it; it may define INT64_MAX. Systems that do not
+have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
+by "configure". */
+
+#if defined HAVE_STDINT_H
+#include <stdint.h>
+#elif defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if defined INT64_MAX || defined int64_t
+#define INT64_OR_DOUBLE int64_t
+#else
+#define INT64_OR_DOUBLE double
+#endif
+
+/* When compiling for use with the Virtual Pascal compiler, these functions
+need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT
+option on the command line. */
+
+#ifdef VPCOMPAT
+#define strlen(s) _strlen(s)
+#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
+#define memcmp(s,c,n) _memcmp(s,c,n)
+#define memcpy(d,s,n) _memcpy(d,s,n)
+#define memmove(d,s,n) _memmove(d,s,n)
+#define memset(s,c,n) _memset(s,c,n)
+#else /* VPCOMPAT */
+
+/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
+define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
+is set. Otherwise, include an emulating function for those systems that have
+neither (there some non-Unix environments where this is the case). */
+
+#ifndef HAVE_MEMMOVE
+#undef memmove /* some systems may have a macro */
+#ifdef HAVE_BCOPY
+#define memmove(a, b, c) bcopy(b, a, c)
+#else /* HAVE_BCOPY */
+static void *
+pcre2_memmove(void *d, const void *s, size_t n)
+{
+size_t i;
+unsigned char *dest = (unsigned char *)d;
+const unsigned char *src = (const unsigned char *)s;
+if (dest > src)
+ {
+ dest += n;
+ src += n;
+ for (i = 0; i < n; ++i) *(--dest) = *(--src);
+ return (void *)dest;
+ }
+else
+ {
+ for (i = 0; i < n; ++i) *dest++ = *src++;
+ return (void *)(dest - n);
+ }
+}
+#define memmove(a, b, c) pcre2_memmove(a, b, c)
+#endif /* not HAVE_BCOPY */
+#endif /* not HAVE_MEMMOVE */
+#endif /* not VPCOMPAT */
+
+/* External (in the C sense) functions and tables that are private to the
+libraries are always referenced using the PRIV macro. This makes it possible
+for pcre2test.c to include some of the source files from the libraries using a
+different PRIV definition to avoid name clashes. It also makes it clear in the
+code that a non-static object is being referenced. */
+
+#ifndef PRIV
+#define PRIV(name) _pcre2_##name
+#endif
+
+/* This is an unsigned int value that no UTF character can ever have, as
+Unicode doesn't go beyond 0x0010ffff. */
+
+#define NOTACHAR 0xffffffff
+
+/* This is the largest valid UTF/Unicode code point. */
+
+#define MAX_UTF_CODE_POINT 0x10ffff
+
+/* Compile-time positive error numbers (all except UTF errors, which are
+negative) start at this value. It should probably never be changed, in case
+some application is checking for specific numbers. There is a copy of this
+#define in pcre2posix.c (which now no longer includes this file). Ideally, a
+way of having a single definition should be found, but as the number is
+unlikely to change, this is not a pressing issue. The original reason for
+having a base other than 0 was to keep the absolute values of compile-time and
+run-time error numbers numerically different, but in the event the code does
+not rely on this. */
+
+#define COMPILE_ERROR_BASE 100
+
+/* Define the default BSR convention. */
+
+#ifdef BSR_ANYCRLF
+#define BSR_DEFAULT PCRE2_BSR_ANYCRLF
+#else
+#define BSR_DEFAULT PCRE2_BSR_UNICODE
+#endif
+
+
+/* ---------------- Basic UTF-8 macros ---------------- */
+
+/* These UTF-8 macros are always defined because they are used in pcre2test for
+handling wide characters in 16-bit and 32-bit modes, even if an 8-bit library
+is not supported. */
+
+/* Tests whether a UTF-8 code point needs extra bytes to decode. */
+
+#define HASUTF8EXTRALEN(c) ((c) >= 0xc0)
+
+/* The following macros were originally written in the form of loops that used
+data from the tables whose names start with PRIV(utf8_table). They were
+rewritten by a user so as not to use loops, because in some environments this
+gives a significant performance advantage, and it seems never to do any harm.
+*/
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, not
+advancing the pointer. */
+
+#define GETUTF8(c, eptr) \
+ { \
+ if ((c & 0x20u) == 0) \
+ c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \
+ else if ((c & 0x10u) == 0) \
+ c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \
+ else if ((c & 0x08u) == 0) \
+ c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \
+ ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \
+ else if ((c & 0x04u) == 0) \
+ c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \
+ ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \
+ (eptr[4] & 0x3fu); \
+ else \
+ c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \
+ ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \
+ ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \
+ }
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
+the pointer. */
+
+#define GETUTF8INC(c, eptr) \
+ { \
+ if ((c & 0x20u) == 0) \
+ c = ((c & 0x1fu) << 6) | (*eptr++ & 0x3fu); \
+ else if ((c & 0x10u) == 0) \
+ { \
+ c = ((c & 0x0fu) << 12) | ((*eptr & 0x3fu) << 6) | (eptr[1] & 0x3fu); \
+ eptr += 2; \
+ } \
+ else if ((c & 0x08u) == 0) \
+ { \
+ c = ((c & 0x07u) << 18) | ((*eptr & 0x3fu) << 12) | \
+ ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \
+ eptr += 3; \
+ } \
+ else if ((c & 0x04u) == 0) \
+ { \
+ c = ((c & 0x03u) << 24) | ((*eptr & 0x3fu) << 18) | \
+ ((eptr[1] & 0x3fu) << 12) | ((eptr[2] & 0x3fu) << 6) | \
+ (eptr[3] & 0x3fu); \
+ eptr += 4; \
+ } \
+ else \
+ { \
+ c = ((c & 0x01u) << 30) | ((*eptr & 0x3fu) << 24) | \
+ ((eptr[1] & 0x3fu) << 18) | ((eptr[2] & 0x3fu) << 12) | \
+ ((eptr[3] & 0x3fu) << 6) | (eptr[4] & 0x3fu); \
+ eptr += 5; \
+ } \
+ }
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, not
+advancing the pointer, incrementing the length. */
+
+#define GETUTF8LEN(c, eptr, len) \
+ { \
+ if ((c & 0x20u) == 0) \
+ { \
+ c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \
+ len++; \
+ } \
+ else if ((c & 0x10u) == 0) \
+ { \
+ c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \
+ len += 2; \
+ } \
+ else if ((c & 0x08u) == 0) \
+ {\
+ c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \
+ ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \
+ len += 3; \
+ } \
+ else if ((c & 0x04u) == 0) \
+ { \
+ c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \
+ ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \
+ (eptr[4] & 0x3fu); \
+ len += 4; \
+ } \
+ else \
+ {\
+ c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \
+ ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \
+ ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \
+ len += 5; \
+ } \
+ }
+
+/* --------------- Whitespace macros ---------------- */
+
+/* Tests for Unicode horizontal and vertical whitespace characters must check a
+number of different values. Using a switch statement for this generates the
+fastest code (no loop, no memory access), and there are several places in the
+interpreter code where this happens. In order to ensure that all the case lists
+remain in step, we use macros so that there is only one place where the lists
+are defined.
+
+These values are also required as lists in pcre2_compile.c when processing \h,
+\H, \v and \V in a character class. The lists are defined in pcre2_tables.c,
+but macros that define the values are here so that all the definitions are
+together. The lists must be in ascending character order, terminated by
+NOTACHAR (which is 0xffffffff).
+
+Any changes should ensure that the various macros are kept in step with each
+other. NOTE: The values also appear in pcre2_jit_compile.c. */
+
+/* -------------- ASCII/Unicode environments -------------- */
+
+#ifndef EBCDIC
+
+/* Character U+180E (Mongolian Vowel Separator) is not included in the list of
+spaces in the Unicode file PropList.txt, and Perl does not recognize it as a
+space. However, in many other sources it is listed as a space and has been in
+PCRE (both APIs) for a long time. */
+
+#define HSPACE_LIST \
+ CHAR_HT, CHAR_SPACE, CHAR_NBSP, \
+ 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
+ 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
+ NOTACHAR
+
+#define HSPACE_MULTIBYTE_CASES \
+ case 0x1680: /* OGHAM SPACE MARK */ \
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ \
+ case 0x2000: /* EN QUAD */ \
+ case 0x2001: /* EM QUAD */ \
+ case 0x2002: /* EN SPACE */ \
+ case 0x2003: /* EM SPACE */ \
+ case 0x2004: /* THREE-PER-EM SPACE */ \
+ case 0x2005: /* FOUR-PER-EM SPACE */ \
+ case 0x2006: /* SIX-PER-EM SPACE */ \
+ case 0x2007: /* FIGURE SPACE */ \
+ case 0x2008: /* PUNCTUATION SPACE */ \
+ case 0x2009: /* THIN SPACE */ \
+ case 0x200A: /* HAIR SPACE */ \
+ case 0x202f: /* NARROW NO-BREAK SPACE */ \
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ \
+ case 0x3000 /* IDEOGRAPHIC SPACE */
+
+#define HSPACE_BYTE_CASES \
+ case CHAR_HT: \
+ case CHAR_SPACE: \
+ case CHAR_NBSP
+
+#define HSPACE_CASES \
+ HSPACE_BYTE_CASES: \
+ HSPACE_MULTIBYTE_CASES
+
+#define VSPACE_LIST \
+ CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR
+
+#define VSPACE_MULTIBYTE_CASES \
+ case 0x2028: /* LINE SEPARATOR */ \
+ case 0x2029 /* PARAGRAPH SEPARATOR */
+
+#define VSPACE_BYTE_CASES \
+ case CHAR_LF: \
+ case CHAR_VT: \
+ case CHAR_FF: \
+ case CHAR_CR: \
+ case CHAR_NEL
+
+#define VSPACE_CASES \
+ VSPACE_BYTE_CASES: \
+ VSPACE_MULTIBYTE_CASES
+
+/* -------------- EBCDIC environments -------------- */
+
+#else
+#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR
+
+#define HSPACE_BYTE_CASES \
+ case CHAR_HT: \
+ case CHAR_SPACE: \
+ case CHAR_NBSP
+
+#define HSPACE_CASES HSPACE_BYTE_CASES
+
+#ifdef EBCDIC_NL25
+#define VSPACE_LIST \
+ CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR
+#else
+#define VSPACE_LIST \
+ CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR
+#endif
+
+#define VSPACE_BYTE_CASES \
+ case CHAR_LF: \
+ case CHAR_VT: \
+ case CHAR_FF: \
+ case CHAR_CR: \
+ case CHAR_NEL
+
+#define VSPACE_CASES VSPACE_BYTE_CASES
+#endif /* EBCDIC */
+
+/* -------------- End of whitespace macros -------------- */
+
+
+/* PCRE2 is able to support several different kinds of newline (CR, LF, CRLF,
+"any" and "anycrlf" at present). The following macros are used to package up
+testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
+modules to indicate in which datablock the parameters exist, and what the
+start/end of string field names are. */
+
+#define NLTYPE_FIXED 0 /* Newline is a fixed length string */
+#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */
+#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */
+
+/* This macro checks for a newline at the given position */
+
+#define IS_NEWLINE(p) \
+ ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+ ((p) < NLBLOCK->PSEND && \
+ PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
+ &(NLBLOCK->nllen), utf)) \
+ : \
+ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
+ UCHAR21TEST(p) == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1]) \
+ ) \
+ )
+
+/* This macro checks for a newline immediately preceding the given position */
+
+#define WAS_NEWLINE(p) \
+ ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+ ((p) > NLBLOCK->PSSTART && \
+ PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
+ &(NLBLOCK->nllen), utf)) \
+ : \
+ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
+ UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \
+ ) \
+ )
+
+/* Private flags containing information about the compiled pattern. The first
+three must not be changed, because whichever is set is actually the number of
+bytes in a code unit in that mode. */
+
+#define PCRE2_MODE8 0x00000001 /* compiled in 8 bit mode */
+#define PCRE2_MODE16 0x00000002 /* compiled in 16 bit mode */
+#define PCRE2_MODE32 0x00000004 /* compiled in 32 bit mode */
+#define PCRE2_FIRSTSET 0x00000010 /* first_code unit is set */
+#define PCRE2_FIRSTCASELESS 0x00000020 /* caseless first code unit */
+#define PCRE2_FIRSTMAPSET 0x00000040 /* bitmap of first code units is set */
+#define PCRE2_LASTSET 0x00000080 /* last code unit is set */
+#define PCRE2_LASTCASELESS 0x00000100 /* caseless last code unit */
+#define PCRE2_STARTLINE 0x00000200 /* start after \n for multiline */
+#define PCRE2_JCHANGED 0x00000400 /* j option used in pattern */
+#define PCRE2_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */
+#define PCRE2_HASTHEN 0x00001000 /* pattern contains (*THEN) */
+#define PCRE2_MATCH_EMPTY 0x00002000 /* pattern can match empty string */
+#define PCRE2_BSR_SET 0x00004000 /* BSR was set in the pattern */
+#define PCRE2_NL_SET 0x00008000 /* newline was set in the pattern */
+#define PCRE2_NOTEMPTY_SET 0x00010000 /* (*NOTEMPTY) used ) keep */
+#define PCRE2_NE_ATST_SET 0x00020000 /* (*NOTEMPTY_ATSTART) used) together */
+#define PCRE2_DEREF_TABLES 0x00040000 /* release character tables */
+#define PCRE2_NOJIT 0x00080000 /* (*NOJIT) used */
+#define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */
+#define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */
+#define PCRE2_HASBKC 0x00400000 /* contains \C */
+
+#define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32)
+
+/* Values for the matchedby field in a match data block. */
+
+enum { PCRE2_MATCHEDBY_INTERPRETER, /* pcre2_match() */
+ PCRE2_MATCHEDBY_DFA_INTERPRETER, /* pcre2_dfa_match() */
+ PCRE2_MATCHEDBY_JIT }; /* pcre2_jit_match() */
+
+/* Magic number to provide a small check against being handed junk. */
+
+#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
+
+/* The maximum remaining length of subject we are prepared to search for a
+req_unit match. */
+
+#define REQ_CU_MAX 1000
+
+/* Offsets for the bitmap tables in the cbits set of tables. Each table
+contains a set of bits for a class map. Some classes are built by combining
+these tables. */
+
+#define cbit_space 0 /* [:space:] or \s */
+#define cbit_xdigit 32 /* [:xdigit:] */
+#define cbit_digit 64 /* [:digit:] or \d */
+#define cbit_upper 96 /* [:upper:] */
+#define cbit_lower 128 /* [:lower:] */
+#define cbit_word 160 /* [:word:] or \w */
+#define cbit_graph 192 /* [:graph:] */
+#define cbit_print 224 /* [:print:] */
+#define cbit_punct 256 /* [:punct:] */
+#define cbit_cntrl 288 /* [:cntrl:] */
+#define cbit_length 320 /* Length of the cbits table */
+
+/* Bit definitions for entries in the ctypes table. */
+
+#define ctype_space 0x01
+#define ctype_letter 0x02
+#define ctype_digit 0x04
+#define ctype_xdigit 0x08
+#define ctype_word 0x10 /* alphanumeric or '_' */
+#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
+
+/* Offsets of the various tables from the base tables pointer, and
+total length of the tables. */
+
+#define lcc_offset 0 /* Lower case */
+#define fcc_offset 256 /* Flip case */
+#define cbits_offset 512 /* Character classes */
+#define ctypes_offset (cbits_offset + cbit_length) /* Character types */
+#define tables_length (ctypes_offset + 256)
+
+
+/* -------------------- Character and string names ------------------------ */
+
+/* If PCRE2 is to support UTF-8 on EBCDIC platforms, we cannot use normal
+character constants like '*' because the compiler would emit their EBCDIC code,
+which is different from their ASCII/UTF-8 code. Instead we define macros for
+the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
+is enabled. When UTF-8 support is not enabled, the definitions use character
+literals. Both character and string versions of each character are needed, and
+there are some longer strings as well.
+
+This means that, on EBCDIC platforms, the PCRE2 library can handle either
+EBCDIC, or UTF-8, but not both. To support both in the same compiled library
+would need different lookups depending on whether PCRE2_UTF was set or not.
+This would make it impossible to use characters in switch/case statements,
+which would reduce performance. For a theoretical use (which nobody has asked
+for) in a minority area (EBCDIC platforms), this is not sensible. Any
+application that did need both could compile two versions of the library, using
+macros to give the functions distinct names. */
+
+#ifndef SUPPORT_UNICODE
+
+/* UTF-8 support is not enabled; use the platform-dependent character literals
+so that PCRE2 works in both ASCII and EBCDIC environments, but only in non-UTF
+mode. Newline characters are problematic in EBCDIC. Though it has CR and LF
+characters, a common practice has been to use its NL (0x15) character as the
+line terminator in C-like processing environments. However, sometimes the LF
+(0x25) character is used instead, according to this Unicode document:
+
+http://unicode.org/standard/reports/tr13/tr13-5.html
+
+PCRE2 defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25
+instead. Whichever is *not* chosen is defined as NEL.
+
+In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the
+same code point. */
+
+#ifdef EBCDIC
+
+#ifndef EBCDIC_NL25
+#define CHAR_NL '\x15'
+#define CHAR_NEL '\x25'
+#define STR_NL "\x15"
+#define STR_NEL "\x25"
+#else
+#define CHAR_NL '\x25'
+#define CHAR_NEL '\x15'
+#define STR_NL "\x25"
+#define STR_NEL "\x15"
+#endif
+
+#define CHAR_LF CHAR_NL
+#define STR_LF STR_NL
+
+#define CHAR_ESC '\047'
+#define CHAR_DEL '\007'
+#define CHAR_NBSP ((unsigned char)'\x41')
+#define STR_ESC "\047"
+#define STR_DEL "\007"
+
+#else /* Not EBCDIC */
+
+/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for
+compatibility. NEL is the Unicode newline character; make sure it is
+a positive value. */
+
+#define CHAR_LF '\n'
+#define CHAR_NL CHAR_LF
+#define CHAR_NEL ((unsigned char)'\x85')
+#define CHAR_ESC '\033'
+#define CHAR_DEL '\177'
+#define CHAR_NBSP ((unsigned char)'\xa0')
+
+#define STR_LF "\n"
+#define STR_NL STR_LF
+#define STR_NEL "\x85"
+#define STR_ESC "\033"
+#define STR_DEL "\177"
+
+#endif /* EBCDIC */
+
+/* The remaining definitions work in both environments. */
+
+#define CHAR_NULL '\0'
+#define CHAR_HT '\t'
+#define CHAR_VT '\v'
+#define CHAR_FF '\f'
+#define CHAR_CR '\r'
+#define CHAR_BS '\b'
+#define CHAR_BEL '\a'
+
+#define CHAR_SPACE ' '
+#define CHAR_EXCLAMATION_MARK '!'
+#define CHAR_QUOTATION_MARK '"'
+#define CHAR_NUMBER_SIGN '#'
+#define CHAR_DOLLAR_SIGN '$'
+#define CHAR_PERCENT_SIGN '%'
+#define CHAR_AMPERSAND '&'
+#define CHAR_APOSTROPHE '\''
+#define CHAR_LEFT_PARENTHESIS '('
+#define CHAR_RIGHT_PARENTHESIS ')'
+#define CHAR_ASTERISK '*'
+#define CHAR_PLUS '+'
+#define CHAR_COMMA ','
+#define CHAR_MINUS '-'
+#define CHAR_DOT '.'
+#define CHAR_SLASH '/'
+#define CHAR_0 '0'
+#define CHAR_1 '1'
+#define CHAR_2 '2'
+#define CHAR_3 '3'
+#define CHAR_4 '4'
+#define CHAR_5 '5'
+#define CHAR_6 '6'
+#define CHAR_7 '7'
+#define CHAR_8 '8'
+#define CHAR_9 '9'
+#define CHAR_COLON ':'
+#define CHAR_SEMICOLON ';'
+#define CHAR_LESS_THAN_SIGN '<'
+#define CHAR_EQUALS_SIGN '='
+#define CHAR_GREATER_THAN_SIGN '>'
+#define CHAR_QUESTION_MARK '?'
+#define CHAR_COMMERCIAL_AT '@'
+#define CHAR_A 'A'
+#define CHAR_B 'B'
+#define CHAR_C 'C'
+#define CHAR_D 'D'
+#define CHAR_E 'E'
+#define CHAR_F 'F'
+#define CHAR_G 'G'
+#define CHAR_H 'H'
+#define CHAR_I 'I'
+#define CHAR_J 'J'
+#define CHAR_K 'K'
+#define CHAR_L 'L'
+#define CHAR_M 'M'
+#define CHAR_N 'N'
+#define CHAR_O 'O'
+#define CHAR_P 'P'
+#define CHAR_Q 'Q'
+#define CHAR_R 'R'
+#define CHAR_S 'S'
+#define CHAR_T 'T'
+#define CHAR_U 'U'
+#define CHAR_V 'V'
+#define CHAR_W 'W'
+#define CHAR_X 'X'
+#define CHAR_Y 'Y'
+#define CHAR_Z 'Z'
+#define CHAR_LEFT_SQUARE_BRACKET '['
+#define CHAR_BACKSLASH '\\'
+#define CHAR_RIGHT_SQUARE_BRACKET ']'
+#define CHAR_CIRCUMFLEX_ACCENT '^'
+#define CHAR_UNDERSCORE '_'
+#define CHAR_GRAVE_ACCENT '`'
+#define CHAR_a 'a'
+#define CHAR_b 'b'
+#define CHAR_c 'c'
+#define CHAR_d 'd'
+#define CHAR_e 'e'
+#define CHAR_f 'f'
+#define CHAR_g 'g'
+#define CHAR_h 'h'
+#define CHAR_i 'i'
+#define CHAR_j 'j'
+#define CHAR_k 'k'
+#define CHAR_l 'l'
+#define CHAR_m 'm'
+#define CHAR_n 'n'
+#define CHAR_o 'o'
+#define CHAR_p 'p'
+#define CHAR_q 'q'
+#define CHAR_r 'r'
+#define CHAR_s 's'
+#define CHAR_t 't'
+#define CHAR_u 'u'
+#define CHAR_v 'v'
+#define CHAR_w 'w'
+#define CHAR_x 'x'
+#define CHAR_y 'y'
+#define CHAR_z 'z'
+#define CHAR_LEFT_CURLY_BRACKET '{'
+#define CHAR_VERTICAL_LINE '|'
+#define CHAR_RIGHT_CURLY_BRACKET '}'
+#define CHAR_TILDE '~'
+
+#define STR_HT "\t"
+#define STR_VT "\v"
+#define STR_FF "\f"
+#define STR_CR "\r"
+#define STR_BS "\b"
+#define STR_BEL "\a"
+
+#define STR_SPACE " "
+#define STR_EXCLAMATION_MARK "!"
+#define STR_QUOTATION_MARK "\""
+#define STR_NUMBER_SIGN "#"
+#define STR_DOLLAR_SIGN "$"
+#define STR_PERCENT_SIGN "%"
+#define STR_AMPERSAND "&"
+#define STR_APOSTROPHE "'"
+#define STR_LEFT_PARENTHESIS "("
+#define STR_RIGHT_PARENTHESIS ")"
+#define STR_ASTERISK "*"
+#define STR_PLUS "+"
+#define STR_COMMA ","
+#define STR_MINUS "-"
+#define STR_DOT "."
+#define STR_SLASH "/"
+#define STR_0 "0"
+#define STR_1 "1"
+#define STR_2 "2"
+#define STR_3 "3"
+#define STR_4 "4"
+#define STR_5 "5"
+#define STR_6 "6"
+#define STR_7 "7"
+#define STR_8 "8"
+#define STR_9 "9"
+#define STR_COLON ":"
+#define STR_SEMICOLON ";"
+#define STR_LESS_THAN_SIGN "<"
+#define STR_EQUALS_SIGN "="
+#define STR_GREATER_THAN_SIGN ">"
+#define STR_QUESTION_MARK "?"
+#define STR_COMMERCIAL_AT "@"
+#define STR_A "A"
+#define STR_B "B"
+#define STR_C "C"
+#define STR_D "D"
+#define STR_E "E"
+#define STR_F "F"
+#define STR_G "G"
+#define STR_H "H"
+#define STR_I "I"
+#define STR_J "J"
+#define STR_K "K"
+#define STR_L "L"
+#define STR_M "M"
+#define STR_N "N"
+#define STR_O "O"
+#define STR_P "P"
+#define STR_Q "Q"
+#define STR_R "R"
+#define STR_S "S"
+#define STR_T "T"
+#define STR_U "U"
+#define STR_V "V"
+#define STR_W "W"
+#define STR_X "X"
+#define STR_Y "Y"
+#define STR_Z "Z"
+#define STR_LEFT_SQUARE_BRACKET "["
+#define STR_BACKSLASH "\\"
+#define STR_RIGHT_SQUARE_BRACKET "]"
+#define STR_CIRCUMFLEX_ACCENT "^"
+#define STR_UNDERSCORE "_"
+#define STR_GRAVE_ACCENT "`"
+#define STR_a "a"
+#define STR_b "b"
+#define STR_c "c"
+#define STR_d "d"
+#define STR_e "e"
+#define STR_f "f"
+#define STR_g "g"
+#define STR_h "h"
+#define STR_i "i"
+#define STR_j "j"
+#define STR_k "k"
+#define STR_l "l"
+#define STR_m "m"
+#define STR_n "n"
+#define STR_o "o"
+#define STR_p "p"
+#define STR_q "q"
+#define STR_r "r"
+#define STR_s "s"
+#define STR_t "t"
+#define STR_u "u"
+#define STR_v "v"
+#define STR_w "w"
+#define STR_x "x"
+#define STR_y "y"
+#define STR_z "z"
+#define STR_LEFT_CURLY_BRACKET "{"
+#define STR_VERTICAL_LINE "|"
+#define STR_RIGHT_CURLY_BRACKET "}"
+#define STR_TILDE "~"
+
+#define STRING_ACCEPT0 "ACCEPT\0"
+#define STRING_COMMIT0 "COMMIT\0"
+#define STRING_F0 "F\0"
+#define STRING_FAIL0 "FAIL\0"
+#define STRING_MARK0 "MARK\0"
+#define STRING_PRUNE0 "PRUNE\0"
+#define STRING_SKIP0 "SKIP\0"
+#define STRING_THEN "THEN"
+
+#define STRING_alpha0 "alpha\0"
+#define STRING_lower0 "lower\0"
+#define STRING_upper0 "upper\0"
+#define STRING_alnum0 "alnum\0"
+#define STRING_ascii0 "ascii\0"
+#define STRING_blank0 "blank\0"
+#define STRING_cntrl0 "cntrl\0"
+#define STRING_digit0 "digit\0"
+#define STRING_graph0 "graph\0"
+#define STRING_print0 "print\0"
+#define STRING_punct0 "punct\0"
+#define STRING_space0 "space\0"
+#define STRING_word0 "word\0"
+#define STRING_xdigit "xdigit"
+
+#define STRING_DEFINE "DEFINE"
+#define STRING_VERSION "VERSION"
+#define STRING_WEIRD_STARTWORD "[:<:]]"
+#define STRING_WEIRD_ENDWORD "[:>:]]"
+
+#define STRING_CR_RIGHTPAR "CR)"
+#define STRING_LF_RIGHTPAR "LF)"
+#define STRING_CRLF_RIGHTPAR "CRLF)"
+#define STRING_ANY_RIGHTPAR "ANY)"
+#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
+#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
+#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
+#define STRING_UTF8_RIGHTPAR "UTF8)"
+#define STRING_UTF16_RIGHTPAR "UTF16)"
+#define STRING_UTF32_RIGHTPAR "UTF32)"
+#define STRING_UTF_RIGHTPAR "UTF)"
+#define STRING_UCP_RIGHTPAR "UCP)"
+#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)"
+#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR "NO_DOTSTAR_ANCHOR)"
+#define STRING_NO_JIT_RIGHTPAR "NO_JIT)"
+#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
+#define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)"
+#define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)"
+#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH="
+#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION="
+#define STRING_MARK "MARK"
+
+#else /* SUPPORT_UNICODE */
+
+/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
+works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
+only. */
+
+#define CHAR_HT '\011'
+#define CHAR_VT '\013'
+#define CHAR_FF '\014'
+#define CHAR_CR '\015'
+#define CHAR_LF '\012'
+#define CHAR_NL CHAR_LF
+#define CHAR_NEL ((unsigned char)'\x85')
+#define CHAR_BS '\010'
+#define CHAR_BEL '\007'
+#define CHAR_ESC '\033'
+#define CHAR_DEL '\177'
+
+#define CHAR_NULL '\0'
+#define CHAR_SPACE '\040'
+#define CHAR_EXCLAMATION_MARK '\041'
+#define CHAR_QUOTATION_MARK '\042'
+#define CHAR_NUMBER_SIGN '\043'
+#define CHAR_DOLLAR_SIGN '\044'
+#define CHAR_PERCENT_SIGN '\045'
+#define CHAR_AMPERSAND '\046'
+#define CHAR_APOSTROPHE '\047'
+#define CHAR_LEFT_PARENTHESIS '\050'
+#define CHAR_RIGHT_PARENTHESIS '\051'
+#define CHAR_ASTERISK '\052'
+#define CHAR_PLUS '\053'
+#define CHAR_COMMA '\054'
+#define CHAR_MINUS '\055'
+#define CHAR_DOT '\056'
+#define CHAR_SLASH '\057'
+#define CHAR_0 '\060'
+#define CHAR_1 '\061'
+#define CHAR_2 '\062'
+#define CHAR_3 '\063'
+#define CHAR_4 '\064'
+#define CHAR_5 '\065'
+#define CHAR_6 '\066'
+#define CHAR_7 '\067'
+#define CHAR_8 '\070'
+#define CHAR_9 '\071'
+#define CHAR_COLON '\072'
+#define CHAR_SEMICOLON '\073'
+#define CHAR_LESS_THAN_SIGN '\074'
+#define CHAR_EQUALS_SIGN '\075'
+#define CHAR_GREATER_THAN_SIGN '\076'
+#define CHAR_QUESTION_MARK '\077'
+#define CHAR_COMMERCIAL_AT '\100'
+#define CHAR_A '\101'
+#define CHAR_B '\102'
+#define CHAR_C '\103'
+#define CHAR_D '\104'
+#define CHAR_E '\105'
+#define CHAR_F '\106'
+#define CHAR_G '\107'
+#define CHAR_H '\110'
+#define CHAR_I '\111'
+#define CHAR_J '\112'
+#define CHAR_K '\113'
+#define CHAR_L '\114'
+#define CHAR_M '\115'
+#define CHAR_N '\116'
+#define CHAR_O '\117'
+#define CHAR_P '\120'
+#define CHAR_Q '\121'
+#define CHAR_R '\122'
+#define CHAR_S '\123'
+#define CHAR_T '\124'
+#define CHAR_U '\125'
+#define CHAR_V '\126'
+#define CHAR_W '\127'
+#define CHAR_X '\130'
+#define CHAR_Y '\131'
+#define CHAR_Z '\132'
+#define CHAR_LEFT_SQUARE_BRACKET '\133'
+#define CHAR_BACKSLASH '\134'
+#define CHAR_RIGHT_SQUARE_BRACKET '\135'
+#define CHAR_CIRCUMFLEX_ACCENT '\136'
+#define CHAR_UNDERSCORE '\137'
+#define CHAR_GRAVE_ACCENT '\140'
+#define CHAR_a '\141'
+#define CHAR_b '\142'
+#define CHAR_c '\143'
+#define CHAR_d '\144'
+#define CHAR_e '\145'
+#define CHAR_f '\146'
+#define CHAR_g '\147'
+#define CHAR_h '\150'
+#define CHAR_i '\151'
+#define CHAR_j '\152'
+#define CHAR_k '\153'
+#define CHAR_l '\154'
+#define CHAR_m '\155'
+#define CHAR_n '\156'
+#define CHAR_o '\157'
+#define CHAR_p '\160'
+#define CHAR_q '\161'
+#define CHAR_r '\162'
+#define CHAR_s '\163'
+#define CHAR_t '\164'
+#define CHAR_u '\165'
+#define CHAR_v '\166'
+#define CHAR_w '\167'
+#define CHAR_x '\170'
+#define CHAR_y '\171'
+#define CHAR_z '\172'
+#define CHAR_LEFT_CURLY_BRACKET '\173'
+#define CHAR_VERTICAL_LINE '\174'
+#define CHAR_RIGHT_CURLY_BRACKET '\175'
+#define CHAR_TILDE '\176'
+#define CHAR_NBSP ((unsigned char)'\xa0')
+
+#define STR_HT "\011"
+#define STR_VT "\013"
+#define STR_FF "\014"
+#define STR_CR "\015"
+#define STR_NL "\012"
+#define STR_BS "\010"
+#define STR_BEL "\007"
+#define STR_ESC "\033"
+#define STR_DEL "\177"
+
+#define STR_SPACE "\040"
+#define STR_EXCLAMATION_MARK "\041"
+#define STR_QUOTATION_MARK "\042"
+#define STR_NUMBER_SIGN "\043"
+#define STR_DOLLAR_SIGN "\044"
+#define STR_PERCENT_SIGN "\045"
+#define STR_AMPERSAND "\046"
+#define STR_APOSTROPHE "\047"
+#define STR_LEFT_PARENTHESIS "\050"
+#define STR_RIGHT_PARENTHESIS "\051"
+#define STR_ASTERISK "\052"
+#define STR_PLUS "\053"
+#define STR_COMMA "\054"
+#define STR_MINUS "\055"
+#define STR_DOT "\056"
+#define STR_SLASH "\057"
+#define STR_0 "\060"
+#define STR_1 "\061"
+#define STR_2 "\062"
+#define STR_3 "\063"
+#define STR_4 "\064"
+#define STR_5 "\065"
+#define STR_6 "\066"
+#define STR_7 "\067"
+#define STR_8 "\070"
+#define STR_9 "\071"
+#define STR_COLON "\072"
+#define STR_SEMICOLON "\073"
+#define STR_LESS_THAN_SIGN "\074"
+#define STR_EQUALS_SIGN "\075"
+#define STR_GREATER_THAN_SIGN "\076"
+#define STR_QUESTION_MARK "\077"
+#define STR_COMMERCIAL_AT "\100"
+#define STR_A "\101"
+#define STR_B "\102"
+#define STR_C "\103"
+#define STR_D "\104"
+#define STR_E "\105"
+#define STR_F "\106"
+#define STR_G "\107"
+#define STR_H "\110"
+#define STR_I "\111"
+#define STR_J "\112"
+#define STR_K "\113"
+#define STR_L "\114"
+#define STR_M "\115"
+#define STR_N "\116"
+#define STR_O "\117"
+#define STR_P "\120"
+#define STR_Q "\121"
+#define STR_R "\122"
+#define STR_S "\123"
+#define STR_T "\124"
+#define STR_U "\125"
+#define STR_V "\126"
+#define STR_W "\127"
+#define STR_X "\130"
+#define STR_Y "\131"
+#define STR_Z "\132"
+#define STR_LEFT_SQUARE_BRACKET "\133"
+#define STR_BACKSLASH "\134"
+#define STR_RIGHT_SQUARE_BRACKET "\135"
+#define STR_CIRCUMFLEX_ACCENT "\136"
+#define STR_UNDERSCORE "\137"
+#define STR_GRAVE_ACCENT "\140"
+#define STR_a "\141"
+#define STR_b "\142"
+#define STR_c "\143"
+#define STR_d "\144"
+#define STR_e "\145"
+#define STR_f "\146"
+#define STR_g "\147"
+#define STR_h "\150"
+#define STR_i "\151"
+#define STR_j "\152"
+#define STR_k "\153"
+#define STR_l "\154"
+#define STR_m "\155"
+#define STR_n "\156"
+#define STR_o "\157"
+#define STR_p "\160"
+#define STR_q "\161"
+#define STR_r "\162"
+#define STR_s "\163"
+#define STR_t "\164"
+#define STR_u "\165"
+#define STR_v "\166"
+#define STR_w "\167"
+#define STR_x "\170"
+#define STR_y "\171"
+#define STR_z "\172"
+#define STR_LEFT_CURLY_BRACKET "\173"
+#define STR_VERTICAL_LINE "\174"
+#define STR_RIGHT_CURLY_BRACKET "\175"
+#define STR_TILDE "\176"
+
+#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0"
+#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0"
+#define STRING_F0 STR_F "\0"
+#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0"
+#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0"
+#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0"
+#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0"
+#define STRING_THEN STR_T STR_H STR_E STR_N
+
+#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0"
+#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0"
+#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0"
+#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0"
+#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0"
+#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0"
+#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0"
+#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0"
+#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0"
+#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0"
+#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0"
+#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0"
+#define STRING_word0 STR_w STR_o STR_r STR_d "\0"
+#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t
+
+#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E
+#define STRING_VERSION STR_V STR_E STR_R STR_S STR_I STR_O STR_N
+#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
+#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
+
+#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
+#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
+#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
+#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
+#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
+#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
+#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
+#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS
+#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_D STR_O STR_T STR_S STR_T STR_A STR_R STR_UNDERSCORE STR_A STR_N STR_C STR_H STR_O STR_R STR_RIGHT_PARENTHESIS
+#define STRING_NO_JIT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_J STR_I STR_T STR_RIGHT_PARENTHESIS
+#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
+#define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS
+#define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS
+#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN
+#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN
+#define STRING_MARK STR_M STR_A STR_R STR_K
+
+#endif /* SUPPORT_UNICODE */
+
+/* -------------------- End of character and string names -------------------*/
+
+/* -------------------- Definitions for compiled patterns -------------------*/
+
+/* Codes for different types of Unicode property */
+
+#define PT_ANY 0 /* Any property - matches all chars */
+#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */
+#define PT_GC 2 /* Specified general characteristic (e.g. L) */
+#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */
+#define PT_SC 4 /* Script (e.g. Han) */
+#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */
+#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */
+#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */
+#define PT_WORD 8 /* Word - L plus N plus underscore */
+#define PT_CLIST 9 /* Pseudo-property: match character list */
+#define PT_UCNC 10 /* Universal Character nameable character */
+#define PT_TABSIZE 11 /* Size of square table for autopossessify tests */
+
+/* The following special properties are used only in XCLASS items, when POSIX
+classes are specified and PCRE2_UCP is set - in other words, for Unicode
+handling of these classes. They are not available via the \p or \P escapes like
+those in the above list, and so they do not take part in the autopossessifying
+table. */
+
+#define PT_PXGRAPH 11 /* [:graph:] - characters that mark the paper */
+#define PT_PXPRINT 12 /* [:print:] - [:graph:] plus non-control spaces */
+#define PT_PXPUNCT 13 /* [:punct:] - punctuation characters */
+
+/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
+contain characters with values greater than 255. */
+
+#define XCL_NOT 0x01 /* Flag: this is a negative class */
+#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
+#define XCL_HASPROP 0x04 /* Flag: property checks are present. */
+
+#define XCL_END 0 /* Marks end of individual items */
+#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
+#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
+#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */
+#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
+
+/* Escape items that are just an encoding of a particular data value. These
+appear in the escapes[] table in pcre2_compile.c as positive numbers. */
+
+#ifndef ESC_a
+#define ESC_a CHAR_BEL
+#endif
+
+#ifndef ESC_e
+#define ESC_e CHAR_ESC
+#endif
+
+#ifndef ESC_f
+#define ESC_f CHAR_FF
+#endif
+
+#ifndef ESC_n
+#define ESC_n CHAR_LF
+#endif
+
+#ifndef ESC_r
+#define ESC_r CHAR_CR
+#endif
+
+/* We can't officially use ESC_t because it is a POSIX reserved identifier
+(presumably because of all the others like size_t). */
+
+#ifndef ESC_tee
+#define ESC_tee CHAR_HT
+#endif
+
+/* These are escaped items that aren't just an encoding of a particular data
+value such as \n. They must have non-zero values, as check_escape() returns 0
+for a data character. In the escapes[] table in pcre2_compile.c their values
+are negated in order to distinguish them from data values.
+
+They must appear here in the same order as in the opcode definitions below, up
+to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL
+mode rather than an escape sequence. It is also used for [^] in JavaScript
+compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves
+like \N.
+
+Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in
+check_escape(). There are tests in the code for an escape greater than ESC_b
+and less than ESC_Z to detect the types that may be repeated. These are the
+types that consume characters. If any new escapes are put in between that don't
+consume a character, that code will have to change. */
+
+enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
+ ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
+ ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
+ ESC_E, ESC_Q, ESC_g, ESC_k };
+
+
+/********************** Opcode definitions ******************/
+
+/****** NOTE NOTE NOTE ******
+
+Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in
+order to the list of escapes immediately above. Furthermore, values up to
+OP_DOLLM must not be changed without adjusting the table called autoposstab in
+pcre2_auto_possess.c
+
+Whenever this list is updated, the two macro definitions that follow must be
+updated to match. The possessification table called "opcode_possessify" in
+pcre2_compile.c must also be updated, and also the tables called "coptable"
+and "poptable" in pcre2_dfa_match.c.
+
+****** NOTE NOTE NOTE ******/
+
+
+/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive,
+are used in a table for deciding whether a repeated character type can be
+auto-possessified. */
+
+#define FIRST_AUTOTAB_OP OP_NOT_DIGIT
+#define LAST_AUTOTAB_LEFT_OP OP_EXTUNI
+#define LAST_AUTOTAB_RIGHT_OP OP_DOLLM
+
+enum {
+ OP_END, /* 0 End of pattern */
+
+ /* Values corresponding to backslashed metacharacters */
+
+ OP_SOD, /* 1 Start of data: \A */
+ OP_SOM, /* 2 Start of match (subject + offset): \G */
+ OP_SET_SOM, /* 3 Set start of match (\K) */
+ OP_NOT_WORD_BOUNDARY, /* 4 \B */
+ OP_WORD_BOUNDARY, /* 5 \b */
+ OP_NOT_DIGIT, /* 6 \D */
+ OP_DIGIT, /* 7 \d */
+ OP_NOT_WHITESPACE, /* 8 \S */
+ OP_WHITESPACE, /* 9 \s */
+ OP_NOT_WORDCHAR, /* 10 \W */
+ OP_WORDCHAR, /* 11 \w */
+
+ OP_ANY, /* 12 Match any character except newline (\N) */
+ OP_ALLANY, /* 13 Match any character */
+ OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
+ OP_NOTPROP, /* 15 \P (not Unicode property) */
+ OP_PROP, /* 16 \p (Unicode property) */
+ OP_ANYNL, /* 17 \R (any newline sequence) */
+ OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */
+ OP_HSPACE, /* 19 \h (horizontal whitespace) */
+ OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */
+ OP_VSPACE, /* 21 \v (vertical whitespace) */
+ OP_EXTUNI, /* 22 \X (extended Unicode sequence */
+ OP_EODN, /* 23 End of data or \n at end of data (\Z) */
+ OP_EOD, /* 24 End of data (\z) */
+
+ /* Line end assertions */
+
+ OP_DOLL, /* 25 End of line - not multiline */
+ OP_DOLLM, /* 26 End of line - multiline */
+ OP_CIRC, /* 27 Start of line - not multiline */
+ OP_CIRCM, /* 28 Start of line - multiline */
+
+ /* Single characters; caseful must precede the caseless ones, and these
+ must remain in this order, and adjacent. */
+
+ OP_CHAR, /* 29 Match one character, casefully */
+ OP_CHARI, /* 30 Match one character, caselessly */
+ OP_NOT, /* 31 Match one character, not the given one, casefully */
+ OP_NOTI, /* 32 Match one character, not the given one, caselessly */
+
+ /* The following sets of 13 opcodes must always be kept in step because
+ the offset from the first one is used to generate the others. */
+
+ /* Repeated characters; caseful must precede the caseless ones */
+
+ OP_STAR, /* 33 The maximizing and minimizing versions of */
+ OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */
+ OP_PLUS, /* 35 the minimizing one second. */
+ OP_MINPLUS, /* 36 */
+ OP_QUERY, /* 37 */
+ OP_MINQUERY, /* 38 */
+
+ OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/
+ OP_MINUPTO, /* 40 */
+ OP_EXACT, /* 41 Exactly n matches */
+
+ OP_POSSTAR, /* 42 Possessified star, caseful */
+ OP_POSPLUS, /* 43 Possessified plus, caseful */
+ OP_POSQUERY, /* 44 Posesssified query, caseful */
+ OP_POSUPTO, /* 45 Possessified upto, caseful */
+
+ /* Repeated characters; caseless must follow the caseful ones */
+
+ OP_STARI, /* 46 */
+ OP_MINSTARI, /* 47 */
+ OP_PLUSI, /* 48 */
+ OP_MINPLUSI, /* 49 */
+ OP_QUERYI, /* 50 */
+ OP_MINQUERYI, /* 51 */
+
+ OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */
+ OP_MINUPTOI, /* 53 */
+ OP_EXACTI, /* 54 */
+
+ OP_POSSTARI, /* 55 Possessified star, caseless */
+ OP_POSPLUSI, /* 56 Possessified plus, caseless */
+ OP_POSQUERYI, /* 57 Posesssified query, caseless */
+ OP_POSUPTOI, /* 58 Possessified upto, caseless */
+
+ /* The negated ones must follow the non-negated ones, and match them */
+ /* Negated repeated character, caseful; must precede the caseless ones */
+
+ OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */
+ OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */
+ OP_NOTPLUS, /* 61 the minimizing one second. They must be in */
+ OP_NOTMINPLUS, /* 62 exactly the same order as those above. */
+ OP_NOTQUERY, /* 63 */
+ OP_NOTMINQUERY, /* 64 */
+
+ OP_NOTUPTO, /* 65 From 0 to n matches, caseful */
+ OP_NOTMINUPTO, /* 66 */
+ OP_NOTEXACT, /* 67 Exactly n matches */
+
+ OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */
+ OP_NOTPOSPLUS, /* 69 */
+ OP_NOTPOSQUERY, /* 70 */
+ OP_NOTPOSUPTO, /* 71 */
+
+ /* Negated repeated character, caseless; must follow the caseful ones */
+
+ OP_NOTSTARI, /* 72 */
+ OP_NOTMINSTARI, /* 73 */
+ OP_NOTPLUSI, /* 74 */
+ OP_NOTMINPLUSI, /* 75 */
+ OP_NOTQUERYI, /* 76 */
+ OP_NOTMINQUERYI, /* 77 */
+
+ OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */
+ OP_NOTMINUPTOI, /* 79 */
+ OP_NOTEXACTI, /* 80 Exactly n matches */
+
+ OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */
+ OP_NOTPOSPLUSI, /* 82 */
+ OP_NOTPOSQUERYI, /* 83 */
+ OP_NOTPOSUPTOI, /* 84 */
+
+ /* Character types */
+
+ OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
+ OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
+ OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */
+ OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */
+ OP_TYPEQUERY, /* 89 */
+ OP_TYPEMINQUERY, /* 90 */
+
+ OP_TYPEUPTO, /* 91 From 0 to n matches */
+ OP_TYPEMINUPTO, /* 92 */
+ OP_TYPEEXACT, /* 93 Exactly n matches */
+
+ OP_TYPEPOSSTAR, /* 94 Possessified versions */
+ OP_TYPEPOSPLUS, /* 95 */
+ OP_TYPEPOSQUERY, /* 96 */
+ OP_TYPEPOSUPTO, /* 97 */
+
+ /* These are used for character classes and back references; only the
+ first six are the same as the sets above. */
+
+ OP_CRSTAR, /* 98 The maximizing and minimizing versions of */
+ OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */
+ OP_CRPLUS, /* 100 the minimizing one second. These codes must */
+ OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */
+ OP_CRQUERY, /* 102 */
+ OP_CRMINQUERY, /* 103 */
+
+ OP_CRRANGE, /* 104 These are different to the three sets above. */
+ OP_CRMINRANGE, /* 105 */
+
+ OP_CRPOSSTAR, /* 106 Possessified versions */
+ OP_CRPOSPLUS, /* 107 */
+ OP_CRPOSQUERY, /* 108 */
+ OP_CRPOSRANGE, /* 109 */
+
+ /* End of quantifier opcodes */
+
+ OP_CLASS, /* 110 Match a character class, chars < 256 only */
+ OP_NCLASS, /* 111 Same, but the bitmap was created from a negative
+ class - the difference is relevant only when a
+ character > 255 is encountered. */
+ OP_XCLASS, /* 112 Extended class for handling > 255 chars within the
+ class. This does both positive and negative. */
+ OP_REF, /* 113 Match a back reference, casefully */
+ OP_REFI, /* 114 Match a back reference, caselessly */
+ OP_DNREF, /* 115 Match a duplicate name backref, casefully */
+ OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */
+ OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */
+ OP_CALLOUT, /* 118 Call out to external function if provided */
+ OP_CALLOUT_STR, /* 119 Call out with string argument */
+
+ OP_ALT, /* 120 Start of alternation */
+ OP_KET, /* 121 End of group that doesn't have an unbounded repeat */
+ OP_KETRMAX, /* 122 These two must remain together and in this */
+ OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */
+ OP_KETRPOS, /* 124 Possessive unlimited repeat. */
+
+ /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
+ asserts must remain in order. */
+
+ OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */
+ OP_ASSERT, /* 126 Positive lookahead */
+ OP_ASSERT_NOT, /* 127 Negative lookahead */
+ OP_ASSERTBACK, /* 128 Positive lookbehind */
+ OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */
+
+ /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately
+ after the assertions, with ONCE first, as there's a test for >= ONCE for a
+ subpattern that isn't an assertion. The POS versions must immediately follow
+ the non-POS versions in each case. */
+
+ OP_ONCE, /* 130 Atomic group, contains captures */
+ OP_ONCE_NC, /* 131 Atomic group containing no captures */
+ OP_BRA, /* 132 Start of non-capturing bracket */
+ OP_BRAPOS, /* 133 Ditto, with unlimited, possessive repeat */
+ OP_CBRA, /* 134 Start of capturing bracket */
+ OP_CBRAPOS, /* 135 Ditto, with unlimited, possessive repeat */
+ OP_COND, /* 136 Conditional group */
+
+ /* These five must follow the previous five, in the same order. There's a
+ check for >= SBRA to distinguish the two sets. */
+
+ OP_SBRA, /* 137 Start of non-capturing bracket, check empty */
+ OP_SBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */
+ OP_SCBRA, /* 139 Start of capturing bracket, check empty */
+ OP_SCBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */
+ OP_SCOND, /* 141 Conditional group, check empty */
+
+ /* The next two pairs must (respectively) be kept together. */
+
+ OP_CREF, /* 142 Used to hold a capture number as condition */
+ OP_DNCREF, /* 143 Used to point to duplicate names as a condition */
+ OP_RREF, /* 144 Used to hold a recursion number as condition */
+ OP_DNRREF, /* 145 Used to point to duplicate names as a condition */
+ OP_FALSE, /* 146 Always false (used by DEFINE and VERSION) */
+ OP_TRUE, /* 147 Always true (used by VERSION) */
+
+ OP_BRAZERO, /* 148 These two must remain together and in this */
+ OP_BRAMINZERO, /* 149 order. */
+ OP_BRAPOSZERO, /* 150 */
+
+ /* These are backtracking control verbs */
+
+ OP_MARK, /* 151 always has an argument */
+ OP_PRUNE, /* 152 */
+ OP_PRUNE_ARG, /* 153 same, but with argument */
+ OP_SKIP, /* 154 */
+ OP_SKIP_ARG, /* 155 same, but with argument */
+ OP_THEN, /* 156 */
+ OP_THEN_ARG, /* 157 same, but with argument */
+ OP_COMMIT, /* 158 */
+
+ /* These are forced failure and success verbs */
+
+ OP_FAIL, /* 159 */
+ OP_ACCEPT, /* 160 */
+ OP_ASSERT_ACCEPT, /* 161 Used inside assertions */
+ OP_CLOSE, /* 162 Used before OP_ACCEPT to close open captures */
+
+ /* This is used to skip a subpattern with a {0} quantifier */
+
+ OP_SKIPZERO, /* 163 */
+
+ /* This is used to identify a DEFINE group during compilation so that it can
+ be checked for having only one branch. It is changed to OP_FALSE before
+ compilation finishes. */
+
+ OP_DEFINE, /* 164 */
+
+ /* This is not an opcode, but is used to check that tables indexed by opcode
+ are the correct length, in order to catch updating errors - there have been
+ some in the past. */
+
+ OP_TABLE_LENGTH
+
+};
+
+/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
+definitions that follow must also be updated to match. There are also tables
+called "opcode_possessify" in pcre2_compile.c and "coptable" and "poptable" in
+pcre2_dfa_exec.c that must be updated. */
+
+
+/* This macro defines textual names for all the opcodes. These are used only
+for debugging, and some of them are only partial names. The macro is referenced
+only in pcre2_printint.c, which fills out the full names in many cases (and in
+some cases doesn't actually use these names at all). */
+
+#define OP_NAME_LIST \
+ "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
+ "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
+ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
+ "extuni", "\\Z", "\\z", \
+ "$", "$", "^", "^", "char", "chari", "not", "noti", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", "{", "{", \
+ "*+","++", "?+", "{", \
+ "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \
+ "Recurse", "Callout", "CalloutStr", \
+ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
+ "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
+ "Once", "Once_NC", \
+ "Bra", "BraPos", "CBra", "CBraPos", \
+ "Cond", \
+ "SBra", "SBraPos", "SCBra", "SCBraPos", \
+ "SCond", \
+ "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", \
+ "Cond false", "Cond true", \
+ "Brazero", "Braminzero", "Braposzero", \
+ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
+ "*THEN", "*THEN", "*COMMIT", "*FAIL", \
+ "*ACCEPT", "*ASSERT_ACCEPT", \
+ "Close", "Skip zero", "Define"
+
+
+/* This macro defines the length of fixed length operations in the compiled
+regex. The lengths are used when searching for specific things, and also in the
+debugging printing of a compiled regex. We use a macro so that it can be
+defined close to the definitions of the opcodes themselves.
+
+As things have been extended, some of these are no longer fixed lenths, but are
+minima instead. For example, the length of a single-character repeat may vary
+in UTF-8 mode. The code that uses this table must know about such things. */
+
+#define OP_LENGTHS \
+ 1, /* End */ \
+ 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
+ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
+ 1, 1, 1, /* Any, AllAny, Anybyte */ \
+ 3, 3, /* \P, \p */ \
+ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
+ 1, /* \X */ \
+ 1, 1, 1, 1, 1, 1, /* \Z, \z, $, $M ^, ^M */ \
+ 2, /* Char - the minimum length */ \
+ 2, /* Chari - the minimum length */ \
+ 2, /* not */ \
+ 2, /* noti */ \
+ /* Positive single-char repeats ** These are */ \
+ 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \
+ 2+IMM2_SIZE, /* exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \
+ 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \
+ 2+IMM2_SIZE, /* exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \
+ /* Negative single-char repeats - only for chars < 256 */ \
+ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \
+ 2+IMM2_SIZE, /* NOT exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \
+ 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \
+ 2+IMM2_SIZE, /* NOT exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \
+ /* Positive type repeats */ \
+ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \
+ 2+IMM2_SIZE, /* Type exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \
+ /* Character class & ref repeats */ \
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
+ 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
+ 1, 1, 1, 1+2*IMM2_SIZE, /* Possessive *+, ++, ?+, CRPOSRANGE */ \
+ 1+(32/sizeof(PCRE2_UCHAR)), /* CLASS */ \
+ 1+(32/sizeof(PCRE2_UCHAR)), /* NCLASS */ \
+ 0, /* XCLASS - variable length */ \
+ 1+IMM2_SIZE, /* REF */ \
+ 1+IMM2_SIZE, /* REFI */ \
+ 1+2*IMM2_SIZE, /* DNREF */ \
+ 1+2*IMM2_SIZE, /* DNREFI */ \
+ 1+LINK_SIZE, /* RECURSE */ \
+ 1+2*LINK_SIZE+1, /* CALLOUT */ \
+ 0, /* CALLOUT_STR - variable length */ \
+ 1+LINK_SIZE, /* Alt */ \
+ 1+LINK_SIZE, /* Ket */ \
+ 1+LINK_SIZE, /* KetRmax */ \
+ 1+LINK_SIZE, /* KetRmin */ \
+ 1+LINK_SIZE, /* KetRpos */ \
+ 1+LINK_SIZE, /* Reverse */ \
+ 1+LINK_SIZE, /* Assert */ \
+ 1+LINK_SIZE, /* Assert not */ \
+ 1+LINK_SIZE, /* Assert behind */ \
+ 1+LINK_SIZE, /* Assert behind not */ \
+ 1+LINK_SIZE, /* ONCE */ \
+ 1+LINK_SIZE, /* ONCE_NC */ \
+ 1+LINK_SIZE, /* BRA */ \
+ 1+LINK_SIZE, /* BRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \
+ 1+LINK_SIZE, /* COND */ \
+ 1+LINK_SIZE, /* SBRA */ \
+ 1+LINK_SIZE, /* SBRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
+ 1+LINK_SIZE, /* SCOND */ \
+ 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* CREF, DNCREF */ \
+ 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* RREF, DNRREF */ \
+ 1, 1, /* FALSE, TRUE */ \
+ 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
+ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
+ 1, 3, /* SKIP, SKIP_ARG */ \
+ 1, 3, /* THEN, THEN_ARG */ \
+ 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \
+ 1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \
+ 1 /* DEFINE */
+
+/* A magic value for OP_RREF to indicate the "any recursion" condition. */
+
+#define RREF_ANY 0xffff
+
+
+/* ---------- Private structures that are mode-independent. ---------- */
+
+/* Structure to hold data for custom memory management. */
+
+typedef struct pcre2_memctl {
+ void * (*malloc)(size_t, void *);
+ void (*free)(void *, void *);
+ void *memory_data;
+} pcre2_memctl;
+
+/* Structure for building a chain of open capturing subpatterns during
+compiling, so that instructions to close them can be compiled when (*ACCEPT) is
+encountered. This is also used to identify subpatterns that contain recursive
+back references to themselves, so that they can be made atomic. */
+
+typedef struct open_capitem {
+ struct open_capitem *next; /* Chain link */
+ uint16_t number; /* Capture number */
+ uint16_t flag; /* Set TRUE if recursive back ref */
+} open_capitem;
+
+/* Layout of the UCP type table that translates property names into types and
+codes. Each entry used to point directly to a name, but to reduce the number of
+relocations in shared libraries, it now has an offset into a single string
+instead. */
+
+typedef struct {
+ uint16_t name_offset;
+ uint16_t type;
+ uint16_t value;
+} ucp_type_table;
+
+/* Unicode character database (UCD) record format */
+
+typedef struct {
+ uint8_t script; /* ucp_Arabic, etc. */
+ uint8_t chartype; /* ucp_Cc, etc. (general categories) */
+ uint8_t gbprop; /* ucp_gbControl, etc. (grapheme break property) */
+ uint8_t caseset; /* offset to multichar other cases or zero */
+ int32_t other_case; /* offset to other case, or zero if none */
+} ucd_record;
+
+/* UCD access macros */
+
+#define UCD_BLOCK_SIZE 128
+#define GET_UCD(ch) (PRIV(ucd_records) + \
+ PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \
+ UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE])
+
+#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype
+#define UCD_SCRIPT(ch) GET_UCD(ch)->script
+#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
+#define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop
+#define UCD_CASESET(ch) GET_UCD(ch)->caseset
+#define UCD_OTHERCASE(ch) ((uint32_t)((int)ch + (int)(GET_UCD(ch)->other_case)))
+
+/* Header for serialized pcre2 codes. */
+
+typedef struct pcre2_serialized_data {
+ uint32_t magic;
+ uint32_t version;
+ uint32_t config;
+ int32_t number_of_codes;
+} pcre2_serialized_data;
+
+
+
+/* ----------------- Items that need PCRE2_CODE_UNIT_WIDTH ----------------- */
+
+/* When this file is included by pcre2test, PCRE2_CODE_UNIT_WIDTH is defined as
+0, so the following items are omitted. */
+
+#if defined PCRE2_CODE_UNIT_WIDTH && PCRE2_CODE_UNIT_WIDTH != 0
+
+/* EBCDIC is supported only for the 8-bit library. */
+
+#if defined EBCDIC && PCRE2_CODE_UNIT_WIDTH != 8
+#error EBCDIC is not supported for the 16-bit or 32-bit libraries
+#endif
+
+/* This is the largest non-UTF code point. */
+
+#define MAX_NON_UTF_CHAR (0xffffffffU >> (32 - PCRE2_CODE_UNIT_WIDTH))
+
+/* Internal shared data tables and variables. These are used by more than one
+of the exported public functions. They have to be "external" in the C sense,
+but are not part of the PCRE2 public API. Although the data for some of them is
+identical in all libraries, they must have different names so that multiple
+libraries can be simultaneously linked to a single application. However, UTF-8
+tables are needed only when compiling the 8-bit library. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+extern const int PRIV(utf8_table1)[];
+extern const int PRIV(utf8_table1_size);
+extern const int PRIV(utf8_table2)[];
+extern const int PRIV(utf8_table3)[];
+extern const uint8_t PRIV(utf8_table4)[];
+#endif
+
+#define _pcre2_OP_lengths PCRE2_SUFFIX(_pcre2_OP_lengths_)
+#define _pcre2_callout_end_delims PCRE2_SUFFIX(_pcre2_callout_end_delims_)
+#define _pcre2_callout_start_delims PCRE2_SUFFIX(_pcre2_callout_start_delims_)
+#define _pcre2_default_compile_context PCRE2_SUFFIX(_pcre2_default_compile_context_)
+#define _pcre2_default_match_context PCRE2_SUFFIX(_pcre2_default_match_context_)
+#define _pcre2_default_tables PCRE2_SUFFIX(_pcre2_default_tables_)
+#define _pcre2_hspace_list PCRE2_SUFFIX(_pcre2_hspace_list_)
+#define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_)
+#define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_)
+#define _pcre2_ucd_records PCRE2_SUFFIX(_pcre2_ucd_records_)
+#define _pcre2_ucd_stage1 PCRE2_SUFFIX(_pcre2_ucd_stage1_)
+#define _pcre2_ucd_stage2 PCRE2_SUFFIX(_pcre2_ucd_stage2_)
+#define _pcre2_ucp_gbtable PCRE2_SUFFIX(_pcre2_ucp_gbtable_)
+#define _pcre2_ucp_gentype PCRE2_SUFFIX(_pcre2_ucp_gentype_)
+#define _pcre2_ucp_typerange PCRE2_SUFFIX(_pcre2_ucp_typerange_)
+#define _pcre2_unicode_version PCRE2_SUFFIX(_pcre2_unicode_version_)
+#define _pcre2_utt PCRE2_SUFFIX(_pcre2_utt_)
+#define _pcre2_utt_names PCRE2_SUFFIX(_pcre2_utt_names_)
+#define _pcre2_utt_size PCRE2_SUFFIX(_pcre2_utt_size_)
+
+extern const uint8_t PRIV(OP_lengths)[];
+extern const uint32_t PRIV(callout_end_delims)[];
+extern const uint32_t PRIV(callout_start_delims)[];
+extern const pcre2_compile_context PRIV(default_compile_context);
+extern const pcre2_match_context PRIV(default_match_context);
+extern const uint8_t PRIV(default_tables)[];
+extern const uint32_t PRIV(hspace_list)[];
+extern const uint32_t PRIV(vspace_list)[];
+extern const uint32_t PRIV(ucd_caseless_sets)[];
+extern const ucd_record PRIV(ucd_records)[];
+extern const uint8_t PRIV(ucd_stage1)[];
+extern const uint16_t PRIV(ucd_stage2)[];
+extern const uint32_t PRIV(ucp_gbtable)[];
+extern const uint32_t PRIV(ucp_gentype)[];
+#ifdef SUPPORT_JIT
+extern const int PRIV(ucp_typerange)[];
+#endif
+extern const char *PRIV(unicode_version);
+extern const ucp_type_table PRIV(utt)[];
+extern const char PRIV(utt_names)[];
+extern const size_t PRIV(utt_size);
+
+/* Mode-dependent macros and hidden and private structures are defined in a
+separate file so that pcre2test can include them at all supported widths. When
+compiling the library, PCRE2_CODE_UNIT_WIDTH will be defined, and we can
+include them at the appropriate width, after setting up suffix macros for the
+private structures. */
+
+#define branch_chain PCRE2_SUFFIX(branch_chain_)
+#define compile_block PCRE2_SUFFIX(compile_block_)
+#define dfa_match_block PCRE2_SUFFIX(dfa_match_block_)
+#define match_block PCRE2_SUFFIX(match_block_)
+#define named_group PCRE2_SUFFIX(named_group_)
+
+#include "pcre2_intmodedep.h"
+
+/* Private "external" functions. These are internal functions that are called
+from modules other than the one in which they are defined. They have to be
+"external" in the C sense, but are not part of the PCRE2 public API. They are
+not referenced from pcre2test, and must not be defined when no code unit width
+is available. */
+
+#define _pcre2_auto_possessify PCRE2_SUFFIX(_pcre2_auto_possessify_)
+#define _pcre2_check_escape PCRE2_SUFFIX(_pcre2_check_escape_)
+#define _pcre2_find_bracket PCRE2_SUFFIX(_pcre2_find_bracket_)
+#define _pcre2_is_newline PCRE2_SUFFIX(_pcre2_is_newline_)
+#define _pcre2_jit_free_rodata PCRE2_SUFFIX(_pcre2_jit_free_rodata_)
+#define _pcre2_jit_free PCRE2_SUFFIX(_pcre2_jit_free_)
+#define _pcre2_jit_get_size PCRE2_SUFFIX(_pcre2_jit_get_size_)
+#define _pcre2_jit_get_target PCRE2_SUFFIX(_pcre2_jit_get_target_)
+#define _pcre2_memctl_malloc PCRE2_SUFFIX(_pcre2_memctl_malloc_)
+#define _pcre2_ord2utf PCRE2_SUFFIX(_pcre2_ord2utf_)
+#define _pcre2_strcmp PCRE2_SUFFIX(_pcre2_strcmp_)
+#define _pcre2_strcmp_c8 PCRE2_SUFFIX(_pcre2_strcmp_c8_)
+#define _pcre2_strcpy_c8 PCRE2_SUFFIX(_pcre2_strcpy_c8_)
+#define _pcre2_strlen PCRE2_SUFFIX(_pcre2_strlen_)
+#define _pcre2_strncmp PCRE2_SUFFIX(_pcre2_strncmp_)
+#define _pcre2_strncmp_c8 PCRE2_SUFFIX(_pcre2_strncmp_c8_)
+#define _pcre2_study PCRE2_SUFFIX(_pcre2_study_)
+#define _pcre2_valid_utf PCRE2_SUFFIX(_pcre2_valid_utf_)
+#define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_)
+#define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_)
+
+extern int _pcre2_auto_possessify(PCRE2_UCHAR *, BOOL,
+ const compile_block *);
+extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,
+ int *, uint32_t, BOOL, compile_block *);
+extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int);
+extern BOOL _pcre2_is_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
+ uint32_t *, BOOL);
+extern void _pcre2_jit_free_rodata(void *, void *);
+extern void _pcre2_jit_free(void *, pcre2_memctl *);
+extern size_t _pcre2_jit_get_size(void *);
+const char * _pcre2_jit_get_target(void);
+extern void * _pcre2_memctl_malloc(size_t, pcre2_memctl *);
+extern unsigned int _pcre2_ord2utf(uint32_t, PCRE2_UCHAR *);
+extern int _pcre2_strcmp(PCRE2_SPTR, PCRE2_SPTR);
+extern int _pcre2_strcmp_c8(PCRE2_SPTR, const char *);
+extern PCRE2_SIZE _pcre2_strcpy_c8(PCRE2_UCHAR *, const char *);
+extern PCRE2_SIZE _pcre2_strlen(PCRE2_SPTR);
+extern int _pcre2_strncmp(PCRE2_SPTR, PCRE2_SPTR, size_t);
+extern int _pcre2_strncmp_c8(PCRE2_SPTR, const char *, size_t);
+extern int _pcre2_study(pcre2_real_code *);
+extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *);
+extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
+ uint32_t *, BOOL);
+extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL);
+#endif /* PCRE2_CODE_UNIT_WIDTH */
+
+/* End of pcre2_internal.h */
diff --git a/thirdparty/pcre2/src/pcre2_intmodedep.h b/thirdparty/pcre2/src/pcre2_intmodedep.h
new file mode 100644
index 0000000000..ebff7e3066
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_intmodedep.h
@@ -0,0 +1,862 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains mode-dependent macro and structure definitions. The
+file is #included by pcre2_internal.h if PCRE2_CODE_UNIT_WIDTH is defined.
+These mode-dependent items are kept in a separate file so that they can also be
+#included multiple times for different code unit widths by pcre2test in order
+to have access to the hidden structures at all supported widths.
+
+Some of the mode-dependent macros are required at different widths for
+different parts of the pcre2test code (in particular, the included
+pcre_printint.c file). We undefine them here so that they can be re-defined for
+multiple inclusions. Not all of these are used in pcre2test, but it's easier
+just to undefine them all. */
+
+#undef ACROSSCHAR
+#undef BACKCHAR
+#undef BYTES2CU
+#undef CU2BYTES
+#undef FORWARDCHAR
+#undef FORWARDCHARTEST
+#undef GET
+#undef GET2
+#undef GETCHAR
+#undef GETCHARINC
+#undef GETCHARINCTEST
+#undef GETCHARLEN
+#undef GETCHARLENTEST
+#undef GETCHARTEST
+#undef GET_EXTRALEN
+#undef HAS_EXTRALEN
+#undef IMM2_SIZE
+#undef MAX_255
+#undef MAX_MARK
+#undef MAX_PATTERN_SIZE
+#undef MAX_UTF_SINGLE_CU
+#undef NOT_FIRSTCU
+#undef PUT
+#undef PUT2
+#undef PUT2INC
+#undef PUTCHAR
+#undef PUTINC
+#undef TABLE_GET
+
+
+
+/* -------------------------- MACROS ----------------------------- */
+
+/* PCRE keeps offsets in its compiled code as at least 16-bit quantities
+(always stored in big-endian order in 8-bit mode) by default. These are used,
+for example, to link from the start of a subpattern to its alternatives and its
+end. The use of 16 bits per offset limits the size of an 8-bit compiled regex
+to around 64K, which is big enough for almost everybody. However, I received a
+request for an even bigger limit. For this reason, and also to make the code
+easier to maintain, the storing and loading of offsets from the compiled code
+unit string is now handled by the macros that are defined here.
+
+The macros are controlled by the value of LINK_SIZE. This defaults to 2, but
+values of 3 or 4 are also supported. */
+
+/* ------------------- 8-bit support ------------------ */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+
+#if LINK_SIZE == 2
+#define PUT(a,n,d) \
+ (a[n] = (PCRE2_UCHAR)((d) >> 8)), \
+ (a[(n)+1] = (PCRE2_UCHAR)((d) & 255))
+#define GET(a,n) \
+ (unsigned int)(((a)[n] << 8) | (a)[(n)+1])
+#define MAX_PATTERN_SIZE (1 << 16)
+
+#elif LINK_SIZE == 3
+#define PUT(a,n,d) \
+ (a[n] = (PCRE2_UCHAR)((d) >> 16)), \
+ (a[(n)+1] = (PCRE2_UCHAR)((d) >> 8)), \
+ (a[(n)+2] = (PCRE2_UCHAR)((d) & 255))
+#define GET(a,n) \
+ (unsigned int)(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
+#define MAX_PATTERN_SIZE (1 << 24)
+
+#elif LINK_SIZE == 4
+#define PUT(a,n,d) \
+ (a[n] = (PCRE2_UCHAR)((d) >> 24)), \
+ (a[(n)+1] = (PCRE2_UCHAR)((d) >> 16)), \
+ (a[(n)+2] = (PCRE2_UCHAR)((d) >> 8)), \
+ (a[(n)+3] = (PCRE2_UCHAR)((d) & 255))
+#define GET(a,n) \
+ (unsigned int)(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
+#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
+
+#else
+#error LINK_SIZE must be 2, 3, or 4
+#endif
+
+
+/* ------------------- 16-bit support ------------------ */
+
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+
+#if LINK_SIZE == 2
+#undef LINK_SIZE
+#define LINK_SIZE 1
+#define PUT(a,n,d) \
+ (a[n] = (PCRE2_UCHAR)(d))
+#define GET(a,n) \
+ (a[n])
+#define MAX_PATTERN_SIZE (1 << 16)
+
+#elif LINK_SIZE == 3 || LINK_SIZE == 4
+#undef LINK_SIZE
+#define LINK_SIZE 2
+#define PUT(a,n,d) \
+ (a[n] = (PCRE2_UCHAR)((d) >> 16)), \
+ (a[(n)+1] = (PCRE2_UCHAR)((d) & 65535))
+#define GET(a,n) \
+ (unsigned int)(((a)[n] << 16) | (a)[(n)+1])
+#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
+
+#else
+#error LINK_SIZE must be 2, 3, or 4
+#endif
+
+
+/* ------------------- 32-bit support ------------------ */
+
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+#undef LINK_SIZE
+#define LINK_SIZE 1
+#define PUT(a,n,d) \
+ (a[n] = (d))
+#define GET(a,n) \
+ (a[n])
+#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
+
+#else
+#error Unsupported compiling mode
+#endif
+
+
+/* --------------- Other mode-specific macros ----------------- */
+
+/* PCRE uses some other (at least) 16-bit quantities that do not change when
+the size of offsets changes. There are used for repeat counts and for other
+things such as capturing parenthesis numbers in back references.
+
+Define the number of code units required to hold a 16-bit count/offset, and
+macros to load and store such a value. For reasons that I do not understand,
+the expression in the 8-bit GET2 macro is treated by gcc as a signed
+expression, even when a is declared as unsigned. It seems that any kind of
+arithmetic results in a signed value. Hence the cast. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define IMM2_SIZE 2
+#define GET2(a,n) (unsigned int)(((a)[n] << 8) | (a)[(n)+1])
+#define PUT2(a,n,d) a[n] = (d) >> 8, a[(n)+1] = (d) & 255
+
+#else /* Code units are 16 or 32 bits */
+#define IMM2_SIZE 1
+#define GET2(a,n) a[n]
+#define PUT2(a,n,d) a[n] = d
+#endif
+
+/* Other macros that are different for 8-bit mode. The MAX_255 macro checks
+whether its argument, which is assumed to be one code unit, is less than 256.
+The maximum length of a MARK name must fit in one code unit; currently it is
+set to 255 or 65535. The TABLE_GET macro is used to access elements of tables
+containing exactly 256 items. When code points can be greater than 255, a check
+is needed before accessing these tables. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define MAX_255(c) TRUE
+#define MAX_MARK ((1u << 8) - 1)
+#ifdef SUPPORT_UNICODE
+#define SUPPORT_WIDE_CHARS
+#endif /* SUPPORT_UNICODE */
+#define TABLE_GET(c, table, default) ((table)[c])
+
+#else /* Code units are 16 or 32 bits */
+#define MAX_255(c) ((c) <= 255u)
+#define MAX_MARK ((1u << 16) - 1)
+#define SUPPORT_WIDE_CHARS
+#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
+#endif
+
+
+
+/* ----------------- Character-handling macros ----------------- */
+
+/* There is a proposed future special "UTF-21" mode, in which only the lowest
+21 bits of a 32-bit character are interpreted as UTF, with the remaining 11
+high-order bits available to the application for other uses. In preparation for
+the future implementation of this mode, there are macros that load a data item
+and, if in this special mode, mask it to 21 bits. These macros all have names
+starting with UCHAR21. In all other modes, including the normal 32-bit
+library, the macros all have the same simple definitions. When the new mode is
+implemented, it is expected that these definitions will be varied appropriately
+using #ifdef when compiling the library that supports the special mode. */
+
+#define UCHAR21(eptr) (*(eptr))
+#define UCHAR21TEST(eptr) (*(eptr))
+#define UCHAR21INC(eptr) (*(eptr)++)
+#define UCHAR21INCTEST(eptr) (*(eptr)++)
+
+/* When UTF encoding is being used, a character is no longer just a single
+byte in 8-bit mode or a single short in 16-bit mode. The macros for character
+handling generate simple sequences when used in the basic mode, and more
+complicated ones for UTF characters. GETCHARLENTEST and other macros are not
+used when UTF is not supported. To make sure they can never even appear when
+UTF support is omitted, we don't even define them. */
+
+#ifndef SUPPORT_UNICODE
+
+/* #define MAX_UTF_SINGLE_CU */
+/* #define HAS_EXTRALEN(c) */
+/* #define GET_EXTRALEN(c) */
+/* #define NOT_FIRSTCU(c) */
+#define GETCHAR(c, eptr) c = *eptr;
+#define GETCHARTEST(c, eptr) c = *eptr;
+#define GETCHARINC(c, eptr) c = *eptr++;
+#define GETCHARINCTEST(c, eptr) c = *eptr++;
+#define GETCHARLEN(c, eptr, len) c = *eptr;
+#define PUTCHAR(c, p) (*p = c, 1)
+/* #define GETCHARLENTEST(c, eptr, len) */
+/* #define BACKCHAR(eptr) */
+/* #define FORWARDCHAR(eptr) */
+/* #define FORWARCCHARTEST(eptr,end) */
+/* #define ACROSSCHAR(condition, eptr, action) */
+
+#else /* SUPPORT_UNICODE */
+
+/* ------------------- 8-bit support ------------------ */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */
+
+/* The largest UTF code point that can be encoded as a single code unit. */
+
+#define MAX_UTF_SINGLE_CU 127
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) HASUTF8EXTRALEN(c)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3fu])
+
+/* Returns TRUE, if the given value is not the first code unit of a UTF
+sequence. */
+
+#define NOT_FIRSTCU(c) (((c) & 0xc0u) == 0x80u)
+
+/* Get the next UTF-8 character, not advancing the pointer. This is called when
+we know we are in UTF-8 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *eptr; \
+ if (c >= 0xc0u) GETUTF8(c, eptr);
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *eptr; \
+ if (utf && c >= 0xc0u) GETUTF8(c, eptr);
+
+/* Get the next UTF-8 character, advancing the pointer. This is called when we
+know we are in UTF-8 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *eptr++; \
+ if (c >= 0xc0u) GETUTF8INC(c, eptr);
+
+/* Get the next character, testing for UTF-8 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-8 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *eptr++; \
+ if (utf && c >= 0xc0u) GETUTF8INC(c, eptr);
+
+/* Get the next UTF-8 character, not advancing the pointer, incrementing length
+if there are extra bytes. This is called when we know we are in UTF-8 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ c = *eptr; \
+ if (c >= 0xc0u) GETUTF8LEN(c, eptr, len);
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
+pointer, incrementing length if there are extra bytes. This is called when we
+do not know if we are in UTF-8 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ c = *eptr; \
+ if (utf && c >= 0xc0u) GETUTF8LEN(c, eptr, len);
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-8 mode - we don't put a test within the macro
+because almost all calls are already within a block of UTF-8 only code. */
+
+#define BACKCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr--
+
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr++
+#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0u) == 0x80u) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ while((condition) && ((eptr) & 0xc0u) == 0x80u) action
+
+/* Deposit a character into memory, returning the number of code units. */
+
+#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \
+ PRIV(ord2utf)(c,p) : (*p = c, 1))
+
+
+/* ------------------- 16-bit support ------------------ */
+
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */
+
+/* The largest UTF code point that can be encoded as a single code unit. */
+
+#define MAX_UTF_SINGLE_CU 65535
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) (((c) & 0xfc00u) == 0xd800u)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) 1
+
+/* Returns TRUE, if the given value is not the first code unit of a UTF
+sequence. */
+
+#define NOT_FIRSTCU(c) (((c) & 0xfc00u) == 0xdc00u)
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer. */
+
+#define GETUTF16(c, eptr) \
+ { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; }
+
+/* Get the next UTF-16 character, not advancing the pointer. This is called when
+we know we are in UTF-16 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *eptr; \
+ if ((c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);
+
+/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
+the pointer. */
+
+#define GETUTF16INC(c, eptr) \
+ { c = (((c & 0x3ffu) << 10) | (*eptr++ & 0x3ffu)) + 0x10000u; }
+
+/* Get the next UTF-16 character, advancing the pointer. This is called when we
+know we are in UTF-16 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *eptr++; \
+ if ((c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);
+
+/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-16 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *eptr++; \
+ if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer, incrementing the length. */
+
+#define GETUTF16LEN(c, eptr, len) \
+ { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; len++; }
+
+/* Get the next UTF-16 character, not advancing the pointer, incrementing
+length if there is a low surrogate. This is called when we know we are in
+UTF-16 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ c = *eptr; \
+ if ((c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);
+
+/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
+pointer, incrementing length if there is a low surrogate. This is called when
+we do not know if we are in UTF-16 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-16 mode - we don't put a test within the
+macro because almost all calls are already within a block of UTF-16 only
+code. */
+
+#define BACKCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr--
+
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr++
+#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00u) == 0xdc00u) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ if ((condition) && ((eptr) & 0xfc00u) == 0xdc00u) action
+
+/* Deposit a character into memory, returning the number of code units. */
+
+#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \
+ PRIV(ord2utf)(c,p) : (*p = c, 1))
+
+
+/* ------------------- 32-bit support ------------------ */
+
+#else
+
+/* These are trivial for the 32-bit library, since all UTF-32 characters fit
+into one PCRE2_UCHAR unit. */
+
+#define MAX_UTF_SINGLE_CU (0x10ffffu)
+#define HAS_EXTRALEN(c) (0)
+#define GET_EXTRALEN(c) (0)
+#define NOT_FIRSTCU(c) (0)
+
+/* Get the next UTF-32 character, not advancing the pointer. This is called when
+we know we are in UTF-32 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *(eptr);
+
+/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *(eptr);
+
+/* Get the next UTF-32 character, advancing the pointer. This is called when we
+know we are in UTF-32 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *((eptr)++);
+
+/* Get the next character, testing for UTF-32 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-32 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *((eptr)++);
+
+/* Get the next UTF-32 character, not advancing the pointer, not incrementing
+length (since all UTF-32 is of length 1). This is called when we know we are in
+UTF-32 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ GETCHAR(c, eptr)
+
+/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the
+pointer, not incrementing the length (since all UTF-32 is of length 1).
+This is called when we do not know if we are in UTF-32 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ GETCHARTEST(c, eptr)
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-32 mode - we don't put a test within the
+macro because almost all calls are already within a block of UTF-32 only
+code.
+
+These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */
+
+#define BACKCHAR(eptr) do { } while (0)
+
+/* Same as above, just in the other direction. */
+
+#define FORWARDCHAR(eptr) do { } while (0)
+#define FORWARDCHARTEST(eptr,end) do { } while (0)
+
+/* Same as above, but it allows a fully customizable form. */
+
+#define ACROSSCHAR(condition, eptr, action) do { } while (0)
+
+/* Deposit a character into memory, returning the number of code units. */
+
+#define PUTCHAR(c, p) (*p = c, 1)
+
+#endif /* UTF-32 character handling */
+#endif /* SUPPORT_UNICODE */
+
+
+/* Mode-dependent macros that have the same definition in all modes. */
+
+#define CU2BYTES(x) ((x)*((PCRE2_CODE_UNIT_WIDTH/8)))
+#define BYTES2CU(x) ((x)/((PCRE2_CODE_UNIT_WIDTH/8)))
+#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
+#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
+
+
+/* ----------------------- HIDDEN STRUCTURES ----------------------------- */
+
+/* NOTE: All these structures *must* start with a pcre2_memctl structure. The
+code that uses them is simpler because it assumes this. */
+
+/* The real general context structure. At present it holds only data for custom
+memory control. */
+
+typedef struct pcre2_real_general_context {
+ pcre2_memctl memctl;
+} pcre2_real_general_context;
+
+/* The real compile context structure */
+
+typedef struct pcre2_real_compile_context {
+ pcre2_memctl memctl;
+ int (*stack_guard)(uint32_t, void *);
+ void *stack_guard_data;
+ const uint8_t *tables;
+ PCRE2_SIZE max_pattern_length;
+ uint16_t bsr_convention;
+ uint16_t newline_convention;
+ uint32_t parens_nest_limit;
+} pcre2_real_compile_context;
+
+/* The real match context structure. */
+
+typedef struct pcre2_real_match_context {
+ pcre2_memctl memctl;
+#ifdef HEAP_MATCH_RECURSE
+ pcre2_memctl stack_memctl;
+#endif
+#ifdef SUPPORT_JIT
+ pcre2_jit_callback jit_callback;
+ void *jit_callback_data;
+#endif
+ int (*callout)(pcre2_callout_block *, void *);
+ void *callout_data;
+ PCRE2_SIZE offset_limit;
+ uint32_t match_limit;
+ uint32_t recursion_limit;
+} pcre2_real_match_context;
+
+/* The real compiled code structure. The type for the blocksize field is
+defined specially because it is required in pcre2_serialize_decode() when
+copying the size from possibly unaligned memory into a variable of the same
+type. Use a macro rather than a typedef to avoid compiler warnings when this
+file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the
+largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit
+argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field
+here.) */
+
+#undef CODE_BLOCKSIZE_TYPE
+#define CODE_BLOCKSIZE_TYPE size_t
+
+#undef LOOKBEHIND_MAX
+#define LOOKBEHIND_MAX UINT16_MAX
+
+typedef struct pcre2_real_code {
+ pcre2_memctl memctl; /* Memory control fields */
+ const uint8_t *tables; /* The character tables */
+ void *executable_jit; /* Pointer to JIT code */
+ uint8_t start_bitmap[32]; /* Bitmap for starting code unit < 256 */
+ CODE_BLOCKSIZE_TYPE blocksize; /* Total (bytes) that was malloc-ed */
+ uint32_t magic_number; /* Paranoid and endianness check */
+ uint32_t compile_options; /* Options passed to pcre2_compile() */
+ uint32_t overall_options; /* Options after processing the pattern */
+ uint32_t flags; /* Various state flags */
+ uint32_t limit_match; /* Limit set in the pattern */
+ uint32_t limit_recursion; /* Limit set in the pattern */
+ uint32_t first_codeunit; /* Starting code unit */
+ uint32_t last_codeunit; /* This codeunit must be seen */
+ uint16_t bsr_convention; /* What \R matches */
+ uint16_t newline_convention; /* What is a newline? */
+ uint16_t max_lookbehind; /* Longest lookbehind (characters) */
+ uint16_t minlength; /* Minimum length of match */
+ uint16_t top_bracket; /* Highest numbered group */
+ uint16_t top_backref; /* Highest numbered back reference */
+ uint16_t name_entry_size; /* Size (code units) of table entries */
+ uint16_t name_count; /* Number of name entries in the table */
+} pcre2_real_code;
+
+/* The real match data structure. */
+
+typedef struct pcre2_real_match_data {
+ pcre2_memctl memctl;
+ const pcre2_real_code *code; /* The pattern used for the match */
+ PCRE2_SPTR subject; /* The subject that was matched */
+ PCRE2_SPTR mark; /* Pointer to last mark */
+ PCRE2_SIZE leftchar; /* Offset to leftmost code unit */
+ PCRE2_SIZE rightchar; /* Offset to rightmost code unit */
+ PCRE2_SIZE startchar; /* Offset to starting code unit */
+ uint16_t matchedby; /* Type of match (normal, JIT, DFA) */
+ uint16_t oveccount; /* Number of pairs */
+ int rc; /* The return code from the match */
+ PCRE2_SIZE ovector[1]; /* The first field */
+} pcre2_real_match_data;
+
+
+/* ----------------------- PRIVATE STRUCTURES ----------------------------- */
+
+/* These structures are not needed for pcre2test. */
+
+#ifndef PCRE2_PCRE2TEST
+
+/* Structures for checking for mutual recursion when scanning compiled or
+parsed code. */
+
+typedef struct recurse_check {
+ struct recurse_check *prev;
+ PCRE2_SPTR group;
+} recurse_check;
+
+typedef struct parsed_recurse_check {
+ struct parsed_recurse_check *prev;
+ uint32_t *groupptr;
+} parsed_recurse_check;
+
+/* Structure for building a cache when filling in recursion offsets. */
+
+typedef struct recurse_cache {
+ PCRE2_SPTR group;
+ int groupnumber;
+} recurse_cache;
+
+/* Structure for maintaining a chain of pointers to the currently incomplete
+branches, for testing for left recursion while compiling. */
+
+typedef struct branch_chain {
+ struct branch_chain *outer;
+ PCRE2_UCHAR *current_branch;
+} branch_chain;
+
+/* Structure for building a list of named groups during the first pass of
+compiling. */
+
+typedef struct named_group {
+ PCRE2_SPTR name; /* Points to the name in the pattern */
+ uint32_t number; /* Group number */
+ uint16_t length; /* Length of the name */
+ uint16_t isdup; /* TRUE if a duplicate */
+} named_group;
+
+/* Structure for passing "static" information around between the functions
+doing the compiling, so that they are thread-safe. */
+
+typedef struct compile_block {
+ pcre2_real_compile_context *cx; /* Points to the compile context */
+ const uint8_t *lcc; /* Points to lower casing table */
+ const uint8_t *fcc; /* Points to case-flipping table */
+ const uint8_t *cbits; /* Points to character type table */
+ const uint8_t *ctypes; /* Points to table of type maps */
+ PCRE2_SPTR start_workspace; /* The start of working space */
+ PCRE2_SPTR start_code; /* The start of the compiled code */
+ PCRE2_SPTR start_pattern; /* The start of the pattern */
+ PCRE2_SPTR end_pattern; /* The end of the pattern */
+ PCRE2_UCHAR *name_table; /* The name/number table */
+ PCRE2_SIZE workspace_size; /* Size of workspace */
+ PCRE2_SIZE small_ref_offset[10]; /* Offsets for \1 to \9 */
+ PCRE2_SIZE erroroffset; /* Offset of error in pattern */
+ uint16_t names_found; /* Number of entries so far */
+ uint16_t name_entry_size; /* Size of each entry */
+ open_capitem *open_caps; /* Chain of open capture items */
+ named_group *named_groups; /* Points to vector in pre-compile */
+ uint32_t named_group_list_size; /* Number of entries in the list */
+ uint32_t external_options; /* External (initial) options */
+ uint32_t external_flags; /* External flag bits to be set */
+ uint32_t bracount; /* Count of capturing parentheses */
+ uint32_t lastcapture; /* Last capture encountered */
+ uint32_t *parsed_pattern; /* Parsed pattern buffer */
+ uint32_t *parsed_pattern_end; /* Parsed pattern should not get here */
+ uint32_t *groupinfo; /* Group info vector */
+ uint32_t top_backref; /* Maximum back reference */
+ uint32_t backref_map; /* Bitmap of low back refs */
+ uint32_t nltype; /* Newline type */
+ uint32_t nllen; /* Newline string length */
+ uint32_t class_range_start; /* Overall class range start */
+ uint32_t class_range_end; /* Overall class range end */
+ PCRE2_UCHAR nl[4]; /* Newline string when fixed length */
+ int max_lookbehind; /* Maximum lookbehind (characters) */
+ int parens_depth; /* Depth of nested parentheses */
+ int assert_depth; /* Depth of nested assertions */
+ int req_varyopt; /* "After variable item" flag for reqbyte */
+ BOOL had_accept; /* (*ACCEPT) encountered */
+ BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
+ BOOL had_recurse; /* Had a recursion or subroutine call */
+ BOOL dupnames; /* Duplicate names exist */
+} compile_block;
+
+/* Structure for keeping the properties of the in-memory stack used
+by the JIT matcher. */
+
+typedef struct pcre2_real_jit_stack {
+ pcre2_memctl memctl;
+ void* stack;
+} pcre2_real_jit_stack;
+
+/* Structure for keeping a chain of heap blocks used for saving ovectors
+during pattern recursion when the ovector is larger than can be saved on
+the system stack. */
+
+typedef struct ovecsave_frame {
+ struct ovecsave_frame *next; /* Next frame on free chain */
+ PCRE2_SIZE saved_ovec[1]; /* First vector element */
+} ovecsave_frame;
+
+/* Structure for items in a linked list that represents an explicit recursive
+call within the pattern; used by pcre_match(). */
+
+typedef struct recursion_info {
+ struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
+ unsigned int group_num; /* Number of group that was called */
+ PCRE2_SIZE *ovec_save; /* Pointer to saved ovector frame */
+ uint32_t saved_capture_last; /* Last capture number */
+ PCRE2_SPTR subject_position; /* Position at start of recursion */
+} recursion_info;
+
+/* A similar structure for pcre_dfa_match(). */
+
+typedef struct dfa_recursion_info {
+ struct dfa_recursion_info *prevrec;
+ PCRE2_SPTR subject_position;
+ uint32_t group_num;
+} dfa_recursion_info;
+
+/* Structure for building a chain of data for holding the values of the subject
+pointer at the start of each subpattern, so as to detect when an empty string
+has been matched by a subpattern - to break infinite loops; used by
+pcre2_match(). */
+
+typedef struct eptrblock {
+ struct eptrblock *epb_prev;
+ PCRE2_SPTR epb_saved_eptr;
+} eptrblock;
+
+/* Structure for passing "static" information around between the functions
+doing traditional NFA matching (pcre2_match() and friends). */
+
+typedef struct match_block {
+ pcre2_memctl memctl; /* For general use */
+#ifdef HEAP_MATCH_RECURSE
+ pcre2_memctl stack_memctl; /* For "stack" frames */
+#endif
+ uint32_t match_call_count; /* As it says */
+ uint32_t match_limit; /* As it says */
+ uint32_t match_limit_recursion; /* As it says */
+ BOOL hitend; /* Hit the end of the subject at some point */
+ BOOL hasthen; /* Pattern contains (*THEN) */
+ const uint8_t *lcc; /* Points to lower casing table */
+ const uint8_t *fcc; /* Points to case-flipping table */
+ const uint8_t *ctypes; /* Points to table of type maps */
+ PCRE2_SIZE *ovector; /* Pointer to the offset vector */
+ PCRE2_SIZE offset_end; /* One past the end */
+ PCRE2_SIZE offset_max; /* The maximum usable for return data */
+ PCRE2_SIZE start_offset; /* The start offset value */
+ PCRE2_SIZE end_offset_top; /* Highwater mark at end of match */
+ uint16_t partial; /* PARTIAL options */
+ uint16_t bsr_convention; /* \R interpretation */
+ uint16_t name_count; /* Number of names in name table */
+ uint16_t name_entry_size; /* Size of entry in names table */
+ PCRE2_SPTR name_table; /* Table of group names */
+ PCRE2_SPTR start_code; /* For use when recursing */
+ PCRE2_SPTR start_subject; /* Start of the subject string */
+ PCRE2_SPTR end_subject; /* End of the subject string */
+ PCRE2_SPTR start_match_ptr; /* Start of matched string */
+ PCRE2_SPTR end_match_ptr; /* Subject position at end match */
+ PCRE2_SPTR start_used_ptr; /* Earliest consulted character */
+ PCRE2_SPTR last_used_ptr; /* Latest consulted character */
+ PCRE2_SPTR mark; /* Mark pointer to pass back on success */
+ PCRE2_SPTR nomatch_mark; /* Mark pointer to pass back on failure */
+ PCRE2_SPTR once_target; /* Where to back up to for atomic groups */
+ uint32_t moptions; /* Match options */
+ uint32_t poptions; /* Pattern options */
+ uint32_t capture_last; /* Most recent capture number + overflow flag */
+ uint32_t skip_arg_count; /* For counting SKIP_ARGs */
+ uint32_t ignore_skip_arg; /* For re-run when SKIP arg name not found */
+ uint32_t match_function_type; /* Set for certain special calls of match() */
+ uint32_t nltype; /* Newline type */
+ uint32_t nllen; /* Newline string length */
+ PCRE2_UCHAR nl[4]; /* Newline string when fixed */
+ eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
+ recursion_info *recursive; /* Linked list of recursion data */
+ ovecsave_frame *ovecsave_chain; /* Linked list of free ovecsave blocks */
+ void *callout_data; /* To pass back to callouts */
+ int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */
+#ifdef HEAP_MATCH_RECURSE
+ void *match_frames_base; /* For remembering malloc'd frames */
+#endif
+} match_block;
+
+/* A similar structure is used for the same purpose by the DFA matching
+functions. */
+
+typedef struct dfa_match_block {
+ pcre2_memctl memctl; /* For general use */
+ PCRE2_SPTR start_code; /* Start of the compiled pattern */
+ PCRE2_SPTR start_subject ; /* Start of the subject string */
+ PCRE2_SPTR end_subject; /* End of subject string */
+ PCRE2_SPTR start_used_ptr; /* Earliest consulted character */
+ PCRE2_SPTR last_used_ptr; /* Latest consulted character */
+ const uint8_t *tables; /* Character tables */
+ PCRE2_SIZE start_offset; /* The start offset value */
+ uint32_t match_limit_recursion; /* As it says */
+ uint32_t moptions; /* Match options */
+ uint32_t poptions; /* Pattern options */
+ uint32_t nltype; /* Newline type */
+ uint32_t nllen; /* Newline string length */
+ PCRE2_UCHAR nl[4]; /* Newline string when fixed */
+ uint16_t bsr_convention; /* \R interpretation */
+ void *callout_data; /* To pass back to callouts */
+ int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */
+ dfa_recursion_info *recursive; /* Linked list of recursion data */
+} dfa_match_block;
+
+#endif /* PCRE2_PCRE2TEST */
+
+/* End of pcre2_intmodedep.h */
diff --git a/thirdparty/pcre2/src/pcre2_jit_compile.c b/thirdparty/pcre2/src/pcre2_jit_compile.c
new file mode 100644
index 0000000000..8dea90a1c5
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_jit_compile.c
@@ -0,0 +1,11501 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+#ifdef SUPPORT_JIT
+
+/* All-in-one: Since we use the JIT compiler only from here,
+we just include it. This way we don't need to touch the build
+system files. */
+
+#define SLJIT_CONFIG_AUTO 1
+#define SLJIT_CONFIG_STATIC 1
+#define SLJIT_VERBOSE 0
+
+#ifdef PCRE2_DEBUG
+#define SLJIT_DEBUG 1
+#else
+#define SLJIT_DEBUG 0
+#endif
+
+#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data)
+#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data)
+
+static void * pcre2_jit_malloc(size_t size, void *allocator_data)
+{
+pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
+return allocator->malloc(size, allocator->memory_data);
+}
+
+static void pcre2_jit_free(void *ptr, void *allocator_data)
+{
+pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
+allocator->free(ptr, allocator->memory_data);
+}
+
+#include "sljit/sljitLir.c"
+
+#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
+#error Unsupported architecture
+#endif
+
+/* Defines for debugging purposes. */
+
+/* 1 - Use unoptimized capturing brackets.
+ 2 - Enable capture_last_ptr (includes option 1). */
+/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
+
+/* 1 - Always have a control head. */
+/* #define DEBUG_FORCE_CONTROL_HEAD 1 */
+
+/* Allocate memory for the regex stack on the real machine stack.
+Fast, but limited size. */
+#define MACHINE_STACK_SIZE 32768
+
+/* Growth rate for stack allocated by the OS. Should be the multiply
+of page size. */
+#define STACK_GROWTH_RATE 8192
+
+/* Enable to check that the allocation could destroy temporaries. */
+#if defined SLJIT_DEBUG && SLJIT_DEBUG
+#define DESTROY_REGISTERS 1
+#endif
+
+/*
+Short summary about the backtracking mechanism empolyed by the jit code generator:
+
+The code generator follows the recursive nature of the PERL compatible regular
+expressions. The basic blocks of regular expressions are condition checkers
+whose execute different commands depending on the result of the condition check.
+The relationship between the operators can be horizontal (concatenation) and
+vertical (sub-expression) (See struct backtrack_common for more details).
+
+ 'ab' - 'a' and 'b' regexps are concatenated
+ 'a+' - 'a' is the sub-expression of the '+' operator
+
+The condition checkers are boolean (true/false) checkers. Machine code is generated
+for the checker itself and for the actions depending on the result of the checker.
+The 'true' case is called as the matching path (expected path), and the other is called as
+the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
+branches on the matching path.
+
+ Greedy star operator (*) :
+ Matching path: match happens.
+ Backtrack path: match failed.
+ Non-greedy star operator (*?) :
+ Matching path: no need to perform a match.
+ Backtrack path: match is required.
+
+The following example shows how the code generated for a capturing bracket
+with two alternatives. Let A, B, C, D are arbirary regular expressions, and
+we have the following regular expression:
+
+ A(B|C)D
+
+The generated code will be the following:
+
+ A matching path
+ '(' matching path (pushing arguments to the stack)
+ B matching path
+ ')' matching path (pushing arguments to the stack)
+ D matching path
+ return with successful match
+
+ D backtrack path
+ ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
+ B backtrack path
+ C expected path
+ jump to D matching path
+ C backtrack path
+ A backtrack path
+
+ Notice, that the order of backtrack code paths are the opposite of the fast
+ code paths. In this way the topmost value on the stack is always belong
+ to the current backtrack code path. The backtrack path must check
+ whether there is a next alternative. If so, it needs to jump back to
+ the matching path eventually. Otherwise it needs to clear out its own stack
+ frame and continue the execution on the backtrack code paths.
+*/
+
+/*
+Saved stack frames:
+
+Atomic blocks and asserts require reloading the values of private data
+when the backtrack mechanism performed. Because of OP_RECURSE, the data
+are not necessarly known in compile time, thus we need a dynamic restore
+mechanism.
+
+The stack frames are stored in a chain list, and have the following format:
+([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
+
+Thus we can restore the private data to a particular point in the stack.
+*/
+
+typedef struct jit_arguments {
+ /* Pointers first. */
+ struct sljit_stack *stack;
+ PCRE2_SPTR str;
+ PCRE2_SPTR begin;
+ PCRE2_SPTR end;
+ pcre2_match_data *match_data;
+ PCRE2_SPTR startchar_ptr;
+ PCRE2_UCHAR *mark_ptr;
+ int (*callout)(pcre2_callout_block *, void *);
+ void *callout_data;
+ /* Everything else after. */
+ sljit_uw offset_limit;
+ sljit_u32 limit_match;
+ sljit_u32 oveccount;
+ sljit_u32 options;
+} jit_arguments;
+
+#define JIT_NUMBER_OF_COMPILE_MODES 3
+
+typedef struct executable_functions {
+ void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
+ void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
+ sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
+ sljit_u32 top_bracket;
+ sljit_u32 limit_match;
+} executable_functions;
+
+typedef struct jump_list {
+ struct sljit_jump *jump;
+ struct jump_list *next;
+} jump_list;
+
+typedef struct stub_list {
+ struct sljit_jump *start;
+ struct sljit_label *quit;
+ struct stub_list *next;
+} stub_list;
+
+typedef struct label_addr_list {
+ struct sljit_label *label;
+ sljit_uw *update_addr;
+ struct label_addr_list *next;
+} label_addr_list;
+
+enum frame_types {
+ no_frame = -1,
+ no_stack = -2
+};
+
+enum control_types {
+ type_mark = 0,
+ type_then_trap = 1
+};
+
+typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
+
+/* The following structure is the key data type for the recursive
+code generator. It is allocated by compile_matchingpath, and contains
+the arguments for compile_backtrackingpath. Must be the first member
+of its descendants. */
+typedef struct backtrack_common {
+ /* Concatenation stack. */
+ struct backtrack_common *prev;
+ jump_list *nextbacktracks;
+ /* Internal stack (for component operators). */
+ struct backtrack_common *top;
+ jump_list *topbacktracks;
+ /* Opcode pointer. */
+ PCRE2_SPTR cc;
+} backtrack_common;
+
+typedef struct assert_backtrack {
+ backtrack_common common;
+ jump_list *condfailed;
+ /* Less than 0 if a frame is not needed. */
+ int framesize;
+ /* Points to our private memory word on the stack. */
+ int private_data_ptr;
+ /* For iterators. */
+ struct sljit_label *matchingpath;
+} assert_backtrack;
+
+typedef struct bracket_backtrack {
+ backtrack_common common;
+ /* Where to coninue if an alternative is successfully matched. */
+ struct sljit_label *alternative_matchingpath;
+ /* For rmin and rmax iterators. */
+ struct sljit_label *recursive_matchingpath;
+ /* For greedy ? operator. */
+ struct sljit_label *zero_matchingpath;
+ /* Contains the branches of a failed condition. */
+ union {
+ /* Both for OP_COND, OP_SCOND. */
+ jump_list *condfailed;
+ assert_backtrack *assert;
+ /* For OP_ONCE. Less than 0 if not needed. */
+ int framesize;
+ } u;
+ /* Points to our private memory word on the stack. */
+ int private_data_ptr;
+} bracket_backtrack;
+
+typedef struct bracketpos_backtrack {
+ backtrack_common common;
+ /* Points to our private memory word on the stack. */
+ int private_data_ptr;
+ /* Reverting stack is needed. */
+ int framesize;
+ /* Allocated stack size. */
+ int stacksize;
+} bracketpos_backtrack;
+
+typedef struct braminzero_backtrack {
+ backtrack_common common;
+ struct sljit_label *matchingpath;
+} braminzero_backtrack;
+
+typedef struct char_iterator_backtrack {
+ backtrack_common common;
+ /* Next iteration. */
+ struct sljit_label *matchingpath;
+ union {
+ jump_list *backtracks;
+ struct {
+ unsigned int othercasebit;
+ PCRE2_UCHAR chr;
+ BOOL enabled;
+ } charpos;
+ } u;
+} char_iterator_backtrack;
+
+typedef struct ref_iterator_backtrack {
+ backtrack_common common;
+ /* Next iteration. */
+ struct sljit_label *matchingpath;
+} ref_iterator_backtrack;
+
+typedef struct recurse_entry {
+ struct recurse_entry *next;
+ /* Contains the function entry. */
+ struct sljit_label *entry;
+ /* Collects the calls until the function is not created. */
+ jump_list *calls;
+ /* Points to the starting opcode. */
+ sljit_sw start;
+} recurse_entry;
+
+typedef struct recurse_backtrack {
+ backtrack_common common;
+ BOOL inlined_pattern;
+} recurse_backtrack;
+
+#define OP_THEN_TRAP OP_TABLE_LENGTH
+
+typedef struct then_trap_backtrack {
+ backtrack_common common;
+ /* If then_trap is not NULL, this structure contains the real
+ then_trap for the backtracking path. */
+ struct then_trap_backtrack *then_trap;
+ /* Points to the starting opcode. */
+ sljit_sw start;
+ /* Exit point for the then opcodes of this alternative. */
+ jump_list *quit;
+ /* Frame size of the current alternative. */
+ int framesize;
+} then_trap_backtrack;
+
+#define MAX_RANGE_SIZE 4
+
+typedef struct compiler_common {
+ /* The sljit ceneric compiler. */
+ struct sljit_compiler *compiler;
+ /* First byte code. */
+ PCRE2_SPTR start;
+ /* Maps private data offset to each opcode. */
+ sljit_s32 *private_data_ptrs;
+ /* Chain list of read-only data ptrs. */
+ void *read_only_data_head;
+ /* Tells whether the capturing bracket is optimized. */
+ sljit_u8 *optimized_cbracket;
+ /* Tells whether the starting offset is a target of then. */
+ sljit_u8 *then_offsets;
+ /* Current position where a THEN must jump. */
+ then_trap_backtrack *then_trap;
+ /* Starting offset of private data for capturing brackets. */
+ sljit_s32 cbra_ptr;
+ /* Output vector starting point. Must be divisible by 2. */
+ sljit_s32 ovector_start;
+ /* Points to the starting character of the current match. */
+ sljit_s32 start_ptr;
+ /* Last known position of the requested byte. */
+ sljit_s32 req_char_ptr;
+ /* Head of the last recursion. */
+ sljit_s32 recursive_head_ptr;
+ /* First inspected character for partial matching.
+ (Needed for avoiding zero length partial matches.) */
+ sljit_s32 start_used_ptr;
+ /* Starting pointer for partial soft matches. */
+ sljit_s32 hit_start;
+ /* Pointer of the match end position. */
+ sljit_s32 match_end_ptr;
+ /* Points to the marked string. */
+ sljit_s32 mark_ptr;
+ /* Recursive control verb management chain. */
+ sljit_s32 control_head_ptr;
+ /* Points to the last matched capture block index. */
+ sljit_s32 capture_last_ptr;
+ /* Fast forward skipping byte code pointer. */
+ PCRE2_SPTR fast_forward_bc_ptr;
+ /* Locals used by fast fail optimization. */
+ sljit_s32 fast_fail_start_ptr;
+ sljit_s32 fast_fail_end_ptr;
+
+ /* Flipped and lower case tables. */
+ const sljit_u8 *fcc;
+ sljit_sw lcc;
+ /* Mode can be PCRE2_JIT_COMPLETE and others. */
+ int mode;
+ /* TRUE, when minlength is greater than 0. */
+ BOOL might_be_empty;
+ /* \K is found in the pattern. */
+ BOOL has_set_som;
+ /* (*SKIP:arg) is found in the pattern. */
+ BOOL has_skip_arg;
+ /* (*THEN) is found in the pattern. */
+ BOOL has_then;
+ /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */
+ BOOL has_skip_in_assert_back;
+ /* Currently in recurse or negative assert. */
+ BOOL local_exit;
+ /* Currently in a positive assert. */
+ BOOL positive_assert;
+ /* Newline control. */
+ int nltype;
+ sljit_u32 nlmax;
+ sljit_u32 nlmin;
+ int newline;
+ int bsr_nltype;
+ sljit_u32 bsr_nlmax;
+ sljit_u32 bsr_nlmin;
+ /* Dollar endonly. */
+ int endonly;
+ /* Tables. */
+ sljit_sw ctypes;
+ /* Named capturing brackets. */
+ PCRE2_SPTR name_table;
+ sljit_sw name_count;
+ sljit_sw name_entry_size;
+
+ /* Labels and jump lists. */
+ struct sljit_label *partialmatchlabel;
+ struct sljit_label *quit_label;
+ struct sljit_label *forced_quit_label;
+ struct sljit_label *accept_label;
+ struct sljit_label *ff_newline_shortcut;
+ stub_list *stubs;
+ label_addr_list *label_addrs;
+ recurse_entry *entries;
+ recurse_entry *currententry;
+ jump_list *partialmatch;
+ jump_list *quit;
+ jump_list *positive_assert_quit;
+ jump_list *forced_quit;
+ jump_list *accept;
+ jump_list *calllimit;
+ jump_list *stackalloc;
+ jump_list *revertframes;
+ jump_list *wordboundary;
+ jump_list *anynewline;
+ jump_list *hspace;
+ jump_list *vspace;
+ jump_list *casefulcmp;
+ jump_list *caselesscmp;
+ jump_list *reset_match;
+ BOOL unset_backref;
+ BOOL alt_circumflex;
+#ifdef SUPPORT_UNICODE
+ BOOL utf;
+ BOOL use_ucp;
+ jump_list *getucd;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ jump_list *utfreadchar;
+ jump_list *utfreadchar16;
+ jump_list *utfreadtype8;
+#endif
+#endif /* SUPPORT_UNICODE */
+} compiler_common;
+
+/* For byte_sequence_compare. */
+
+typedef struct compare_context {
+ int length;
+ int sourcereg;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ int ucharptr;
+ union {
+ sljit_s32 asint;
+ sljit_u16 asushort;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ sljit_u8 asbyte;
+ sljit_u8 asuchars[4];
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ sljit_u16 asuchars[2];
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+ sljit_u32 asuchars[1];
+#endif
+ } c;
+ union {
+ sljit_s32 asint;
+ sljit_u16 asushort;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ sljit_u8 asbyte;
+ sljit_u8 asuchars[4];
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ sljit_u16 asuchars[2];
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+ sljit_u32 asuchars[1];
+#endif
+ } oc;
+#endif
+} compare_context;
+
+/* Undefine sljit macros. */
+#undef CMP
+
+/* Used for accessing the elements of the stack. */
+#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_sw))
+
+#define TMP1 SLJIT_R0
+#define TMP2 SLJIT_R2
+#define TMP3 SLJIT_R3
+#define STR_PTR SLJIT_S0
+#define STR_END SLJIT_S1
+#define STACK_TOP SLJIT_R1
+#define STACK_LIMIT SLJIT_S2
+#define COUNT_MATCH SLJIT_S3
+#define ARGUMENTS SLJIT_S4
+#define RETURN_ADDR SLJIT_R4
+
+/* Local space layout. */
+/* These two locals can be used by the current opcode. */
+#define LOCALS0 (0 * sizeof(sljit_sw))
+#define LOCALS1 (1 * sizeof(sljit_sw))
+/* Two local variables for possessive quantifiers (char1 cannot use them). */
+#define POSSESSIVE0 (2 * sizeof(sljit_sw))
+#define POSSESSIVE1 (3 * sizeof(sljit_sw))
+/* Max limit of recursions. */
+#define LIMIT_MATCH (4 * sizeof(sljit_sw))
+/* The output vector is stored on the stack, and contains pointers
+to characters. The vector data is divided into two groups: the first
+group contains the start / end character pointers, and the second is
+the start pointers when the end of the capturing group has not yet reached. */
+#define OVECTOR_START (common->ovector_start)
+#define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
+#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
+#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define MOV_UCHAR SLJIT_MOV_U8
+#define MOVU_UCHAR SLJIT_MOVU_U8
+#define IN_UCHARS(x) (x)
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+#define MOV_UCHAR SLJIT_MOV_U16
+#define MOVU_UCHAR SLJIT_MOVU_U16
+#define UCHAR_SHIFT (1)
+#define IN_UCHARS(x) ((x) * 2)
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+#define MOV_UCHAR SLJIT_MOV_U32
+#define MOVU_UCHAR SLJIT_MOVU_U32
+#define UCHAR_SHIFT (2)
+#define IN_UCHARS(x) ((x) * 4)
+#else
+#error Unsupported compiling mode
+#endif
+
+/* Shortcuts. */
+#define DEFINE_COMPILER \
+ struct sljit_compiler *compiler = common->compiler
+#define OP1(op, dst, dstw, src, srcw) \
+ sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
+#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
+ sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
+#define LABEL() \
+ sljit_emit_label(compiler)
+#define JUMP(type) \
+ sljit_emit_jump(compiler, (type))
+#define JUMPTO(type, label) \
+ sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
+#define JUMPHERE(jump) \
+ sljit_set_label((jump), sljit_emit_label(compiler))
+#define SET_LABEL(jump, label) \
+ sljit_set_label((jump), (label))
+#define CMP(type, src1, src1w, src2, src2w) \
+ sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
+#define CMPTO(type, src1, src1w, src2, src2w, label) \
+ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
+#define OP_FLAGS(op, dst, dstw, src, srcw, type) \
+ sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
+#define GET_LOCAL_BASE(dst, dstw, offset) \
+ sljit_get_local_base(compiler, (dst), (dstw), (offset))
+
+#define READ_CHAR_MAX 0x7fffffff
+
+static PCRE2_SPTR bracketend(PCRE2_SPTR cc)
+{
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+do cc += GET(cc, 1); while (*cc == OP_ALT);
+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
+cc += 1 + LINK_SIZE;
+return cc;
+}
+
+static int no_alternatives(PCRE2_SPTR cc)
+{
+int count = 0;
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+do
+ {
+ cc += GET(cc, 1);
+ count++;
+ }
+while (*cc == OP_ALT);
+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
+return count;
+}
+
+/* Functions whose might need modification for all new supported opcodes:
+ next_opcode
+ check_opcode_types
+ set_private_data_ptrs
+ get_framesize
+ init_frame
+ get_private_data_copy_length
+ copy_private_data
+ compile_matchingpath
+ compile_backtrackingpath
+*/
+
+static PCRE2_SPTR next_opcode(compiler_common *common, PCRE2_SPTR cc)
+{
+SLJIT_UNUSED_ARG(common);
+switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_NOTPROP:
+ case OP_PROP:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
+ case OP_CRPOSRANGE:
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_REF:
+ case OP_REFI:
+ case OP_DNREF:
+ case OP_DNREFI:
+ case OP_RECURSE:
+ case OP_CALLOUT:
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_REVERSE:
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ case OP_SCOND:
+ case OP_CREF:
+ case OP_DNCREF:
+ case OP_RREF:
+ case OP_DNRREF:
+ case OP_FALSE:
+ case OP_TRUE:
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ case OP_PRUNE:
+ case OP_SKIP:
+ case OP_THEN:
+ case OP_COMMIT:
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_CLOSE:
+ case OP_SKIPZERO:
+ return cc + PRIV(OP_lengths)[*cc];
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ cc += PRIV(OP_lengths)[*cc];
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ return cc;
+
+ /* Special cases. */
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ return cc + PRIV(OP_lengths)[*cc] - 1;
+
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UNICODE
+ if (common->utf) return NULL;
+#endif
+ return cc + 1;
+
+ case OP_CALLOUT_STR:
+ return cc + GET(cc, 1 + 2*LINK_SIZE);
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+ return cc + GET(cc, 1);
+#endif
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ return cc + 1 + 2 + cc[1];
+
+ default:
+ /* All opcodes are supported now! */
+ SLJIT_ASSERT_STOP();
+ return NULL;
+ }
+}
+
+static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend)
+{
+int count;
+PCRE2_SPTR slot;
+PCRE2_SPTR assert_back_end = cc - 1;
+
+/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ common->has_set_som = TRUE;
+ common->might_be_empty = TRUE;
+ cc += 1;
+ break;
+
+ case OP_REF:
+ case OP_REFI:
+ common->optimized_cbracket[GET2(cc, 1)] = 0;
+ cc += 1 + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ case OP_SCOND:
+ /* Only AUTO_CALLOUT can insert this opcode. We do
+ not intend to support this case. */
+ if (cc[1 + LINK_SIZE] == OP_CALLOUT || cc[1 + LINK_SIZE] == OP_CALLOUT_STR)
+ return FALSE;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CREF:
+ common->optimized_cbracket[GET2(cc, 1)] = 0;
+ cc += 1 + IMM2_SIZE;
+ break;
+
+ case OP_DNREF:
+ case OP_DNREFI:
+ case OP_DNCREF:
+ count = GET2(cc, 1 + IMM2_SIZE);
+ slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
+ while (count-- > 0)
+ {
+ common->optimized_cbracket[GET2(slot, 0)] = 0;
+ slot += common->name_entry_size;
+ }
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ case OP_RECURSE:
+ /* Set its value only once. */
+ if (common->recursive_head_ptr == 0)
+ {
+ common->recursive_head_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CALLOUT:
+ case OP_CALLOUT_STR:
+ if (common->capture_last_ptr == 0)
+ {
+ common->capture_last_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+ cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE);
+ break;
+
+ case OP_ASSERTBACK:
+ slot = bracketend(cc);
+ if (slot > assert_back_end)
+ assert_back_end = slot;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_THEN_ARG:
+ common->has_then = TRUE;
+ common->control_head_ptr = 1;
+ /* Fall through. */
+
+ case OP_PRUNE_ARG:
+ case OP_MARK:
+ if (common->mark_ptr == 0)
+ {
+ common->mark_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+ cc += 1 + 2 + cc[1];
+ break;
+
+ case OP_THEN:
+ common->has_then = TRUE;
+ common->control_head_ptr = 1;
+ cc += 1;
+ break;
+
+ case OP_SKIP:
+ if (cc < assert_back_end)
+ common->has_skip_in_assert_back = TRUE;
+ cc += 1;
+ break;
+
+ case OP_SKIP_ARG:
+ common->control_head_ptr = 1;
+ common->has_skip_arg = TRUE;
+ if (cc < assert_back_end)
+ common->has_skip_in_assert_back = TRUE;
+ cc += 1 + 2 + cc[1];
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ if (cc == NULL)
+ return FALSE;
+ break;
+ }
+ }
+return TRUE;
+}
+
+static BOOL is_accelerated_repeat(PCRE2_SPTR cc)
+{
+switch(*cc)
+ {
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI);
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ return TRUE;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+ cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(PCRE2_UCHAR)));
+#else
+ cc += (1 + (32 / sizeof(PCRE2_UCHAR)));
+#endif
+
+ switch(*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ return TRUE;
+ }
+ break;
+ }
+return FALSE;
+}
+
+static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start)
+{
+PCRE2_SPTR cc = common->start;
+PCRE2_SPTR end;
+
+/* Skip not repeated brackets. */
+while (TRUE)
+ {
+ switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ /* Zero width assertions. */
+ cc++;
+ continue;
+ }
+
+ if (*cc != OP_BRA && *cc != OP_CBRA)
+ break;
+
+ end = cc + GET(cc, 1);
+ if (*end != OP_KET || PRIVATE_DATA(end) != 0)
+ return FALSE;
+ if (*cc == OP_CBRA)
+ {
+ if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
+ return FALSE;
+ cc += IMM2_SIZE;
+ }
+ cc += 1 + LINK_SIZE;
+ }
+
+if (is_accelerated_repeat(cc))
+ {
+ common->fast_forward_bc_ptr = cc;
+ common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
+ *private_data_start += sizeof(sljit_sw);
+ return TRUE;
+ }
+return FALSE;
+}
+
+static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth)
+{
+ PCRE2_SPTR next_alt;
+
+ SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA);
+
+ if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
+ return;
+
+ next_alt = bracketend(cc) - (1 + LINK_SIZE);
+ if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0)
+ return;
+
+ do
+ {
+ next_alt = cc + GET(cc, 1);
+
+ cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
+
+ while (TRUE)
+ {
+ switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ /* Zero width assertions. */
+ cc++;
+ continue;
+ }
+ break;
+ }
+
+ if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA))
+ detect_fast_fail(common, cc, private_data_start, depth - 1);
+
+ if (is_accelerated_repeat(cc))
+ {
+ common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
+
+ if (common->fast_fail_start_ptr == 0)
+ common->fast_fail_start_ptr = *private_data_start;
+
+ *private_data_start += sizeof(sljit_sw);
+ common->fast_fail_end_ptr = *private_data_start;
+
+ if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
+ return;
+ }
+
+ cc = next_alt;
+ }
+ while (*cc == OP_ALT);
+}
+
+static int get_class_iterator_size(PCRE2_SPTR cc)
+{
+sljit_u32 min;
+sljit_u32 max;
+switch(*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRPLUS:
+ return 2;
+
+ case OP_CRMINSTAR:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ return 1;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(cc, 1);
+ max = GET2(cc, 1 + IMM2_SIZE);
+ if (max == 0)
+ return (*cc == OP_CRRANGE) ? 2 : 1;
+ max -= min;
+ if (max > 2)
+ max = 2;
+ return max;
+
+ default:
+ return 0;
+ }
+}
+
+static BOOL detect_repeat(compiler_common *common, PCRE2_SPTR begin)
+{
+PCRE2_SPTR end = bracketend(begin);
+PCRE2_SPTR next;
+PCRE2_SPTR next_end;
+PCRE2_SPTR max_end;
+PCRE2_UCHAR type;
+sljit_sw length = end - begin;
+sljit_s32 min, max, i;
+
+/* Detect fixed iterations first. */
+if (end[-(1 + LINK_SIZE)] != OP_KET)
+ return FALSE;
+
+/* Already detected repeat. */
+if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
+ return TRUE;
+
+next = end;
+min = 1;
+while (1)
+ {
+ if (*next != *begin)
+ break;
+ next_end = bracketend(next);
+ if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
+ break;
+ next = next_end;
+ min++;
+ }
+
+if (min == 2)
+ return FALSE;
+
+max = 0;
+max_end = next;
+if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
+ {
+ type = *next;
+ while (1)
+ {
+ if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
+ break;
+ next_end = bracketend(next + 2 + LINK_SIZE);
+ if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
+ break;
+ next = next_end;
+ max++;
+ }
+
+ if (next[0] == type && next[1] == *begin && max >= 1)
+ {
+ next_end = bracketend(next + 1);
+ if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
+ {
+ for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
+ if (*next_end != OP_KET)
+ break;
+
+ if (i == max)
+ {
+ common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
+ common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
+ /* +2 the original and the last. */
+ common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
+ if (min == 1)
+ return TRUE;
+ min--;
+ max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
+ }
+ }
+ }
+ }
+
+if (min >= 3)
+ {
+ common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
+ common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
+ common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
+ return TRUE;
+ }
+
+return FALSE;
+}
+
+#define CASE_ITERATOR_PRIVATE_DATA_1 \
+ case OP_MINSTAR: \
+ case OP_MINPLUS: \
+ case OP_QUERY: \
+ case OP_MINQUERY: \
+ case OP_MINSTARI: \
+ case OP_MINPLUSI: \
+ case OP_QUERYI: \
+ case OP_MINQUERYI: \
+ case OP_NOTMINSTAR: \
+ case OP_NOTMINPLUS: \
+ case OP_NOTQUERY: \
+ case OP_NOTMINQUERY: \
+ case OP_NOTMINSTARI: \
+ case OP_NOTMINPLUSI: \
+ case OP_NOTQUERYI: \
+ case OP_NOTMINQUERYI:
+
+#define CASE_ITERATOR_PRIVATE_DATA_2A \
+ case OP_STAR: \
+ case OP_PLUS: \
+ case OP_STARI: \
+ case OP_PLUSI: \
+ case OP_NOTSTAR: \
+ case OP_NOTPLUS: \
+ case OP_NOTSTARI: \
+ case OP_NOTPLUSI:
+
+#define CASE_ITERATOR_PRIVATE_DATA_2B \
+ case OP_UPTO: \
+ case OP_MINUPTO: \
+ case OP_UPTOI: \
+ case OP_MINUPTOI: \
+ case OP_NOTUPTO: \
+ case OP_NOTMINUPTO: \
+ case OP_NOTUPTOI: \
+ case OP_NOTMINUPTOI:
+
+#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
+ case OP_TYPEMINSTAR: \
+ case OP_TYPEMINPLUS: \
+ case OP_TYPEQUERY: \
+ case OP_TYPEMINQUERY:
+
+#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
+ case OP_TYPESTAR: \
+ case OP_TYPEPLUS:
+
+#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
+ case OP_TYPEUPTO: \
+ case OP_TYPEMINUPTO:
+
+static void set_private_data_ptrs(compiler_common *common, int *private_data_start, PCRE2_SPTR ccend)
+{
+PCRE2_SPTR cc = common->start;
+PCRE2_SPTR alternative;
+PCRE2_SPTR end = NULL;
+int private_data_ptr = *private_data_start;
+int space, size, bracketlen;
+BOOL repeat_check = TRUE;
+
+while (cc < ccend)
+ {
+ space = 0;
+ size = 0;
+ bracketlen = 0;
+ if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
+ break;
+
+ if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
+ {
+ if (detect_repeat(common, cc))
+ {
+ /* These brackets are converted to repeats, so no global
+ based single character repeat is allowed. */
+ if (cc >= end)
+ end = bracketend(cc);
+ }
+ }
+ repeat_check = TRUE;
+
+ switch(*cc)
+ {
+ case OP_KET:
+ if (common->private_data_ptrs[cc + 1 - common->start] != 0)
+ {
+ common->private_data_ptrs[cc - common->start] = private_data_ptr;
+ private_data_ptr += sizeof(sljit_sw);
+ cc += common->private_data_ptrs[cc + 1 - common->start];
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ common->private_data_ptrs[cc - common->start] = private_data_ptr;
+ private_data_ptr += sizeof(sljit_sw);
+ bracketlen = 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ common->private_data_ptrs[cc - common->start] = private_data_ptr;
+ private_data_ptr += sizeof(sljit_sw);
+ bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ common->private_data_ptrs[cc - common->start] = private_data_ptr;
+ private_data_ptr += sizeof(sljit_sw);
+ }
+ bracketlen = 1 + LINK_SIZE;
+ break;
+
+ case OP_BRA:
+ bracketlen = 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ repeat_check = FALSE;
+ size = 1;
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_1
+ space = 1;
+ size = -2;
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_2A
+ space = 2;
+ size = -2;
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_2B
+ space = 2;
+ size = -(2 + IMM2_SIZE);
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_1
+ space = 1;
+ size = 1;
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
+ if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
+ space = 2;
+ size = 1;
+ break;
+
+ case OP_TYPEUPTO:
+ if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
+ space = 2;
+ size = 1 + IMM2_SIZE;
+ break;
+
+ case OP_TYPEMINUPTO:
+ space = 2;
+ size = 1 + IMM2_SIZE;
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ space = get_class_iterator_size(cc + size);
+ size = 1 + 32 / sizeof(PCRE2_UCHAR);
+ break;
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+ space = get_class_iterator_size(cc + size);
+ size = GET(cc, 1);
+ break;
+#endif
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+ /* Character iterators, which are not inside a repeated bracket,
+ gets a private slot instead of allocating it on the stack. */
+ if (space > 0 && cc >= end)
+ {
+ common->private_data_ptrs[cc - common->start] = private_data_ptr;
+ private_data_ptr += sizeof(sljit_sw) * space;
+ }
+
+ if (size != 0)
+ {
+ if (size < 0)
+ {
+ cc += -size;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ }
+ else
+ cc += size;
+ }
+
+ if (bracketlen > 0)
+ {
+ if (cc >= end)
+ {
+ end = bracketend(cc);
+ if (end[-1 - LINK_SIZE] == OP_KET)
+ end = NULL;
+ }
+ cc += bracketlen;
+ }
+ }
+*private_data_start = private_data_ptr;
+}
+
+/* Returns with a frame_types (always < 0) if no need for frame. */
+static int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head)
+{
+int length = 0;
+int possessive = 0;
+BOOL stack_restore = FALSE;
+BOOL setsom_found = recursive;
+BOOL setmark_found = recursive;
+/* The last capture is a local variable even for recursions. */
+BOOL capture_last_found = FALSE;
+
+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
+SLJIT_ASSERT(common->control_head_ptr != 0);
+*needs_control_head = TRUE;
+#else
+*needs_control_head = FALSE;
+#endif
+
+if (ccend == NULL)
+ {
+ ccend = bracketend(cc) - (1 + LINK_SIZE);
+ if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
+ {
+ possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
+ /* This is correct regardless of common->capture_last_ptr. */
+ capture_last_found = TRUE;
+ }
+ cc = next_opcode(common, cc);
+ }
+
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ SLJIT_ASSERT(common->has_set_som);
+ stack_restore = TRUE;
+ if (!setsom_found)
+ {
+ length += 2;
+ setsom_found = TRUE;
+ }
+ cc += 1;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_THEN_ARG:
+ SLJIT_ASSERT(common->mark_ptr != 0);
+ stack_restore = TRUE;
+ if (!setmark_found)
+ {
+ length += 2;
+ setmark_found = TRUE;
+ }
+ if (common->control_head_ptr != 0)
+ *needs_control_head = TRUE;
+ cc += 1 + 2 + cc[1];
+ break;
+
+ case OP_RECURSE:
+ stack_restore = TRUE;
+ if (common->has_set_som && !setsom_found)
+ {
+ length += 2;
+ setsom_found = TRUE;
+ }
+ if (common->mark_ptr != 0 && !setmark_found)
+ {
+ length += 2;
+ setmark_found = TRUE;
+ }
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ length += 2;
+ capture_last_found = TRUE;
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ stack_restore = TRUE;
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ length += 2;
+ capture_last_found = TRUE;
+ }
+ length += 3;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_THEN:
+ stack_restore = TRUE;
+ if (common->control_head_ptr != 0)
+ *needs_control_head = TRUE;
+ cc ++;
+ break;
+
+ default:
+ stack_restore = TRUE;
+ /* Fall through. */
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_NOTPROP:
+ case OP_PROP:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_XCLASS:
+
+ case OP_CALLOUT:
+ case OP_CALLOUT_STR:
+
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+/* Possessive quantifiers can use a special case. */
+if (SLJIT_UNLIKELY(possessive == length))
+ return stack_restore ? no_frame : no_stack;
+
+if (length > 0)
+ return length + 1;
+return stack_restore ? no_frame : no_stack;
+}
+
+static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop, BOOL recursive)
+{
+DEFINE_COMPILER;
+BOOL setsom_found = recursive;
+BOOL setmark_found = recursive;
+/* The last capture is a local variable even for recursions. */
+BOOL capture_last_found = FALSE;
+int offset;
+
+/* >= 1 + shortest item size (2) */
+SLJIT_UNUSED_ARG(stacktop);
+SLJIT_ASSERT(stackpos >= stacktop + 2);
+
+stackpos = STACK(stackpos);
+if (ccend == NULL)
+ {
+ ccend = bracketend(cc) - (1 + LINK_SIZE);
+ if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
+ cc = next_opcode(common, cc);
+ }
+
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ SLJIT_ASSERT(common->has_set_som);
+ if (!setsom_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ setsom_found = TRUE;
+ }
+ cc += 1;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_THEN_ARG:
+ SLJIT_ASSERT(common->mark_ptr != 0);
+ if (!setmark_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ setmark_found = TRUE;
+ }
+ cc += 1 + 2 + cc[1];
+ break;
+
+ case OP_RECURSE:
+ if (common->has_set_som && !setsom_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ setsom_found = TRUE;
+ }
+ if (common->mark_ptr != 0 && !setmark_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ setmark_found = TRUE;
+ }
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ capture_last_found = TRUE;
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ capture_last_found = TRUE;
+ }
+ offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
+ stackpos += (int)sizeof(sljit_sw);
+
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
+SLJIT_ASSERT(stackpos == STACK(stacktop));
+}
+
+static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL needs_control_head)
+{
+int private_data_length = needs_control_head ? 3 : 2;
+int size;
+PCRE2_SPTR alternative;
+/* Calculate the sum of the private machine words. */
+while (cc < ccend)
+ {
+ size = 0;
+ switch(*cc)
+ {
+ case OP_KET:
+ if (PRIVATE_DATA(cc) != 0)
+ {
+ private_data_length++;
+ SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
+ cc += PRIVATE_DATA(cc + 1);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ private_data_length++;
+ SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
+ private_data_length++;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ private_data_length += 2;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ private_data_length++;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_1
+ if (PRIVATE_DATA(cc))
+ private_data_length++;
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_2A
+ if (PRIVATE_DATA(cc))
+ private_data_length += 2;
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_2B
+ if (PRIVATE_DATA(cc))
+ private_data_length += 2;
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_1
+ if (PRIVATE_DATA(cc))
+ private_data_length++;
+ cc += 1;
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
+ if (PRIVATE_DATA(cc))
+ private_data_length += 2;
+ cc += 1;
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
+ if (PRIVATE_DATA(cc))
+ private_data_length += 2;
+ cc += 1 + IMM2_SIZE;
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+ size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);
+#else
+ size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
+#endif
+ if (PRIVATE_DATA(cc))
+ private_data_length += get_class_iterator_size(cc + size);
+ cc += size;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ }
+SLJIT_ASSERT(cc == ccend);
+return private_data_length;
+}
+
+static void copy_private_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
+ BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
+{
+DEFINE_COMPILER;
+int srcw[2];
+int count, size;
+BOOL tmp1next = TRUE;
+BOOL tmp1empty = TRUE;
+BOOL tmp2empty = TRUE;
+PCRE2_SPTR alternative;
+enum {
+ start,
+ loop,
+ end
+} status;
+
+status = save ? start : loop;
+stackptr = STACK(stackptr - 2);
+stacktop = STACK(stacktop - 1);
+
+if (!save)
+ {
+ stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_sw);
+ tmp1empty = FALSE;
+ }
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_sw);
+ tmp2empty = FALSE;
+ }
+ /* The tmp1next must be TRUE in either way. */
+ }
+
+do
+ {
+ count = 0;
+ switch(status)
+ {
+ case start:
+ SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
+ count = 1;
+ srcw[0] = common->recursive_head_ptr;
+ if (needs_control_head)
+ {
+ SLJIT_ASSERT(common->control_head_ptr != 0);
+ count = 2;
+ srcw[1] = common->control_head_ptr;
+ }
+ status = loop;
+ break;
+
+ case loop:
+ if (cc >= ccend)
+ {
+ status = end;
+ break;
+ }
+
+ switch(*cc)
+ {
+ case OP_KET:
+ if (PRIVATE_DATA(cc) != 0)
+ {
+ count = 1;
+ srcw[0] = PRIVATE_DATA(cc);
+ SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
+ cc += PRIVATE_DATA(cc + 1);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ count = 1;
+ srcw[0] = PRIVATE_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
+ {
+ count = 1;
+ srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ }
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ count = 2;
+ srcw[0] = PRIVATE_DATA(cc);
+ srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ count = 1;
+ srcw[0] = PRIVATE_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_1
+ if (PRIVATE_DATA(cc))
+ {
+ count = 1;
+ srcw[0] = PRIVATE_DATA(cc);
+ }
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_2A
+ if (PRIVATE_DATA(cc))
+ {
+ count = 2;
+ srcw[0] = PRIVATE_DATA(cc);
+ srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
+ }
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ CASE_ITERATOR_PRIVATE_DATA_2B
+ if (PRIVATE_DATA(cc))
+ {
+ count = 2;
+ srcw[0] = PRIVATE_DATA(cc);
+ srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
+ }
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_1
+ if (PRIVATE_DATA(cc))
+ {
+ count = 1;
+ srcw[0] = PRIVATE_DATA(cc);
+ }
+ cc += 1;
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
+ if (PRIVATE_DATA(cc))
+ {
+ count = 2;
+ srcw[0] = PRIVATE_DATA(cc);
+ srcw[1] = srcw[0] + sizeof(sljit_sw);
+ }
+ cc += 1;
+ break;
+
+ CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
+ if (PRIVATE_DATA(cc))
+ {
+ count = 2;
+ srcw[0] = PRIVATE_DATA(cc);
+ srcw[1] = srcw[0] + sizeof(sljit_sw);
+ }
+ cc += 1 + IMM2_SIZE;
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+ size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);
+#else
+ size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
+#endif
+ if (PRIVATE_DATA(cc))
+ switch(get_class_iterator_size(cc + size))
+ {
+ case 1:
+ count = 1;
+ srcw[0] = PRIVATE_DATA(cc);
+ break;
+
+ case 2:
+ count = 2;
+ srcw[0] = PRIVATE_DATA(cc);
+ srcw[1] = srcw[0] + sizeof(sljit_sw);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ cc += size;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ break;
+
+ case end:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ while (count > 0)
+ {
+ count--;
+ if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_sw);
+ }
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
+ tmp1empty = FALSE;
+ tmp1next = FALSE;
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_sw);
+ }
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
+ tmp2empty = FALSE;
+ tmp1next = TRUE;
+ }
+ }
+ else
+ {
+ if (tmp1next)
+ {
+ SLJIT_ASSERT(!tmp1empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0);
+ tmp1empty = stackptr >= stacktop;
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_sw);
+ }
+ tmp1next = FALSE;
+ }
+ else
+ {
+ SLJIT_ASSERT(!tmp2empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0);
+ tmp2empty = stackptr >= stacktop;
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_sw);
+ }
+ tmp1next = TRUE;
+ }
+ }
+ }
+ }
+while (status != end);
+
+if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_sw);
+ }
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_sw);
+ }
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_sw);
+ }
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_sw);
+ }
+ }
+ }
+SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
+}
+
+static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_u8 *current_offset)
+{
+PCRE2_SPTR end = bracketend(cc);
+BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
+
+/* Assert captures then. */
+if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
+ current_offset = NULL;
+/* Conditional block does not. */
+if (*cc == OP_COND || *cc == OP_SCOND)
+ has_alternatives = FALSE;
+
+cc = next_opcode(common, cc);
+if (has_alternatives)
+ current_offset = common->then_offsets + (cc - common->start);
+
+while (cc < end)
+ {
+ if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
+ cc = set_then_offsets(common, cc, current_offset);
+ else
+ {
+ if (*cc == OP_ALT && has_alternatives)
+ current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
+ if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
+ *current_offset = 1;
+ cc = next_opcode(common, cc);
+ }
+ }
+
+return end;
+}
+
+#undef CASE_ITERATOR_PRIVATE_DATA_1
+#undef CASE_ITERATOR_PRIVATE_DATA_2A
+#undef CASE_ITERATOR_PRIVATE_DATA_2B
+#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
+#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
+#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
+
+static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
+{
+return (value & (value - 1)) == 0;
+}
+
+static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
+{
+while (list)
+ {
+ /* sljit_set_label is clever enough to do nothing
+ if either the jump or the label is NULL. */
+ SET_LABEL(list->jump, label);
+ list = list->next;
+ }
+}
+
+static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)
+{
+jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
+if (list_item)
+ {
+ list_item->next = *list;
+ list_item->jump = jump;
+ *list = list_item;
+ }
+}
+
+static void add_stub(compiler_common *common, struct sljit_jump *start)
+{
+DEFINE_COMPILER;
+stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
+
+if (list_item)
+ {
+ list_item->start = start;
+ list_item->quit = LABEL();
+ list_item->next = common->stubs;
+ common->stubs = list_item;
+ }
+}
+
+static void flush_stubs(compiler_common *common)
+{
+DEFINE_COMPILER;
+stub_list *list_item = common->stubs;
+
+while (list_item)
+ {
+ JUMPHERE(list_item->start);
+ add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
+ JUMPTO(SLJIT_JUMP, list_item->quit);
+ list_item = list_item->next;
+ }
+common->stubs = NULL;
+}
+
+static void add_label_addr(compiler_common *common, sljit_uw *update_addr)
+{
+DEFINE_COMPILER;
+label_addr_list *label_addr;
+
+label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
+if (label_addr == NULL)
+ return;
+label_addr->label = LABEL();
+label_addr->update_addr = update_addr;
+label_addr->next = common->label_addrs;
+common->label_addrs = label_addr;
+}
+
+static SLJIT_INLINE void count_match(compiler_common *common)
+{
+DEFINE_COMPILER;
+
+OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
+add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
+}
+
+static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
+{
+/* May destroy all locals and registers except TMP2. */
+DEFINE_COMPILER;
+
+SLJIT_ASSERT(size > 0);
+OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
+#ifdef DESTROY_REGISTERS
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
+OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
+#endif
+add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
+}
+
+static SLJIT_INLINE void free_stack(compiler_common *common, int size)
+{
+DEFINE_COMPILER;
+
+SLJIT_ASSERT(size > 0);
+OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
+}
+
+static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
+{
+DEFINE_COMPILER;
+sljit_uw *result;
+
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
+if (SLJIT_UNLIKELY(result == NULL))
+ {
+ sljit_set_compiler_memory_error(compiler);
+ return NULL;
+ }
+
+*(void**)result = common->read_only_data_head;
+common->read_only_data_head = (void *)result;
+return result + 1;
+}
+
+static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+sljit_s32 i;
+
+/* At this point we can freely use all temporary registers. */
+SLJIT_ASSERT(length > 1);
+/* TMP1 returns with begin - 1. */
+OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
+if (length < 8)
+ {
+ for (i = 1; i < length; i++)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
+ }
+else
+ {
+ GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, loop);
+ }
+}
+
+static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
+{
+DEFINE_COMPILER;
+sljit_s32 i;
+
+SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr);
+
+OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0);
+}
+
+static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+int i;
+
+SLJIT_ASSERT(length > 1);
+/* OVECTOR(1) contains the "string begin - 1" constant. */
+if (length > 2)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
+if (length < 8)
+ {
+ for (i = 2; i < length; i++)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
+ }
+else
+ {
+ GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, loop);
+ }
+
+OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
+if (common->control_head_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
+}
+
+static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)
+{
+while (current != NULL)
+ {
+ switch (current[-2])
+ {
+ case type_then_trap:
+ break;
+
+ case type_mark:
+ if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[-3]) == 0)
+ return current[-4];
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ SLJIT_ASSERT(current > (sljit_sw*)current[-1]);
+ current = (sljit_sw*)current[-1];
+ }
+return -1;
+}
+
+static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+
+/* At this point we can freely use all registers. */
+OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);
+
+OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
+OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
+OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data),
+ SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
+
+GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
+OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
+
+loop = LABEL();
+OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
+OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
+/* Copy the integer value to the output buffer */
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+SLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8);
+if (sizeof(PCRE2_SIZE) == 4)
+ OP1(SLJIT_MOVU_U32, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0);
+else
+ OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
+JUMPTO(SLJIT_NOT_ZERO, loop);
+
+/* Calculate the return value, which is the maximum ovector value. */
+if (topbracket > 1)
+ {
+ GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
+
+ /* OVECTOR(0) is never equal to SLJIT_S2. */
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
+ OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
+ CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
+ }
+else
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+}
+
+static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
+{
+DEFINE_COMPILER;
+sljit_s32 mov_opcode;
+
+SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2);
+SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
+ && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));
+
+OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP),
+ common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr);
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);
+
+/* Store match begin and end. */
+OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
+OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data));
+
+mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
+
+OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0);
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0);
+
+OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S0, 0);
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector) + sizeof(PCRE2_SIZE), STR_END, 0);
+
+JUMPTO(SLJIT_JUMP, quit);
+}
+
+static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
+{
+/* May destroy TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
+ {
+ /* The value of -1 must be kept for start_used_ptr! */
+ OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);
+ /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
+ is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
+ jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
+else if (common->mode == PCRE2_JIT_PARTIAL_HARD)
+ {
+ jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
+}
+
+static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR cc)
+{
+/* Detects if the character has an othercase. */
+unsigned int c;
+
+#ifdef SUPPORT_UNICODE
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c > 127)
+ {
+ return c != UCD_OTHERCASE(c);
+ }
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ return common->fcc[c] != c;
+#endif
+ }
+else
+#endif
+ c = *cc;
+return MAX_255(c) ? common->fcc[c] != c : FALSE;
+}
+
+static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
+{
+/* Returns with the othercase. */
+#ifdef SUPPORT_UNICODE
+if (common->utf && c > 127)
+ {
+ return UCD_OTHERCASE(c);
+ }
+#endif
+return TABLE_GET(c, common->fcc, c);
+}
+
+static unsigned int char_get_othercase_bit(compiler_common *common, PCRE2_SPTR cc)
+{
+/* Detects if the character and its othercase has only 1 bit difference. */
+unsigned int c, oc, bit;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+int n;
+#endif
+
+#ifdef SUPPORT_UNICODE
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c <= 127)
+ oc = common->fcc[c];
+ else
+ {
+ oc = UCD_OTHERCASE(c);
+ }
+ }
+else
+ {
+ c = *cc;
+ oc = TABLE_GET(c, common->fcc, c);
+ }
+#else
+c = *cc;
+oc = TABLE_GET(c, common->fcc, c);
+#endif
+
+SLJIT_ASSERT(c != oc);
+
+bit = c ^ oc;
+/* Optimized for English alphabet. */
+if (c <= 127 && bit == 0x20)
+ return (0 << 8) | 0x20;
+
+/* Since c != oc, they must have at least 1 bit difference. */
+if (!is_powerof2(bit))
+ return 0;
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+
+#ifdef SUPPORT_UNICODE
+if (common->utf && c > 127)
+ {
+ n = GET_EXTRALEN(*cc);
+ while ((bit & 0x3f) == 0)
+ {
+ n--;
+ bit >>= 6;
+ }
+ return (n << 8) | bit;
+ }
+#endif /* SUPPORT_UNICODE */
+return (0 << 8) | bit;
+
+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+
+#ifdef SUPPORT_UNICODE
+if (common->utf && c > 65535)
+ {
+ if (bit >= (1 << 10))
+ bit >>= 10;
+ else
+ return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
+ }
+#endif /* SUPPORT_UNICODE */
+return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
+
+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
+}
+
+static void check_partial(compiler_common *common, BOOL force)
+{
+/* Checks whether a partial matching is occurred. Does not modify registers. */
+DEFINE_COMPILER;
+struct sljit_jump *jump = NULL;
+
+SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE);
+
+if (common->mode == PCRE2_JIT_COMPLETE)
+ return;
+
+if (!force)
+ jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
+else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
+ jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
+
+if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
+else
+ {
+ if (common->partialmatchlabel != NULL)
+ JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
+ else
+ add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
+ }
+
+if (jump != NULL)
+ JUMPHERE(jump);
+}
+
+static void check_str_end(compiler_common *common, jump_list **end_reached)
+{
+/* Does not affect registers. Usually used in a tight spot. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+if (common->mode == PCRE2_JIT_COMPLETE)
+ {
+ add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ return;
+ }
+
+jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
+ {
+ add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
+ add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
+ }
+else
+ {
+ add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
+ if (common->partialmatchlabel != NULL)
+ JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
+ else
+ add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
+ }
+JUMPHERE(jump);
+}
+
+static void detect_partial_match(compiler_common *common, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+if (common->mode == PCRE2_JIT_COMPLETE)
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ return;
+ }
+
+/* Partial matching mode. */
+jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
+add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
+if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ }
+else
+ {
+ if (common->partialmatchlabel != NULL)
+ JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
+ else
+ add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
+ }
+JUMPHERE(jump);
+}
+
+static void peek_char(compiler_common *common, sljit_u32 max)
+{
+/* Reads the character into TMP1, keeps STR_PTR.
+Does not check STR_END. TMP2 Destroyed. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_jump *jump;
+#endif
+
+SLJIT_UNUSED_ARG(max);
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+ if (max < 128) return;
+
+ jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
+if (common->utf)
+ {
+ if (max < 0xd800) return;
+
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ /* TMP2 contains the high surrogate. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
+#endif
+}
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+
+static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass)
+{
+/* Tells whether the character codes below 128 are enough
+to determine a match. */
+const sljit_u8 value = nclass ? 0xff : 0;
+const sljit_u8 *end = bitset + 32;
+
+bitset += 16;
+do
+ {
+ if (*bitset++ != value)
+ return FALSE;
+ }
+while (bitset < end);
+return TRUE;
+}
+
+static void read_char7_type(compiler_common *common, BOOL full_read)
+{
+/* Reads the precise character type of a character into TMP1, if the character
+is less than 128. Otherwise it returns with zero. Does not check STR_END. The
+full_read argument tells whether characters above max are accepted or not. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+SLJIT_ASSERT(common->utf);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+
+if (full_read)
+ {
+ jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
+}
+
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
+
+static void read_char_range(compiler_common *common, sljit_u32 min, sljit_u32 max, BOOL update_str_ptr)
+{
+/* Reads the precise value of a character into TMP1, if the character is
+between min and max (c >= min && c <= max). Otherwise it returns with a value
+outside the range. Does not check STR_END. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_jump *jump;
+#endif
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+struct sljit_jump *jump2;
+#endif
+
+SLJIT_UNUSED_ARG(update_str_ptr);
+SLJIT_UNUSED_ARG(min);
+SLJIT_UNUSED_ARG(max);
+SLJIT_ASSERT(min <= max);
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+ if (max < 128 && !update_str_ptr) return;
+
+ jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ if (min >= 0x10000)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
+ if (update_str_ptr)
+ OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+ if (!update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump2);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
+ }
+ else if (min >= 0x800 && max <= 0xffff)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
+ if (update_str_ptr)
+ OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ if (!update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump2);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
+ }
+ else if (max >= 0x800)
+ add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ else if (max < 128)
+ {
+ OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ }
+ else
+ {
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (!update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ else
+ OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
+ }
+ JUMPHERE(jump);
+ }
+#endif
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
+if (common->utf)
+ {
+ if (max >= 0x10000)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ /* TMP2 contains the high surrogate. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump);
+ return;
+ }
+
+ if (max < 0xd800 && !update_str_ptr) return;
+
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ if (max >= 0xd800)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
+ JUMPHERE(jump);
+ }
+#endif
+}
+
+static SLJIT_INLINE void read_char(compiler_common *common)
+{
+read_char_range(common, 0, READ_CHAR_MAX, TRUE);
+}
+
+static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
+{
+/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+struct sljit_jump *jump;
+#endif
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+struct sljit_jump *jump2;
+#endif
+
+SLJIT_UNUSED_ARG(update_str_ptr);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+ /* This can be an extra read in some situations, but hopefully
+ it is needed in most cases. */
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
+ if (!update_str_ptr)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+ jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ JUMPHERE(jump2);
+ }
+ else
+ add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
+ JUMPHERE(jump);
+ return;
+ }
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+/* The ctypes array contains only 256 values. */
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+JUMPHERE(jump);
+#endif
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
+if (common->utf && update_str_ptr)
+ {
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ JUMPHERE(jump);
+ }
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */
+}
+
+static void skip_char_back(compiler_common *common)
+{
+/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+#if PCRE2_CODE_UNIT_WIDTH == 8
+struct sljit_label *label;
+
+if (common->utf)
+ {
+ label = LABEL();
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
+ return;
+ }
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ return;
+ }
+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+}
+
+static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
+{
+/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+if (nltype == NLTYPE_ANY)
+ {
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));
+ }
+else if (nltype == NLTYPE_ANYCRLF)
+ {
+ if (jumpifmatch)
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ }
+ else
+ {
+ jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ JUMPHERE(jump);
+ }
+ }
+else
+ {
+ SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
+ add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+}
+
+#ifdef SUPPORT_UNICODE
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+static void do_utfreadchar(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character. TMP1 contains the first byte
+of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+/* Searching for the first zero. */
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
+jump = JUMP(SLJIT_NOT_ZERO);
+/* Two byte sequence. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+jump = JUMP(SLJIT_NOT_ZERO);
+/* Three byte sequence. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+/* Four byte sequence. */
+JUMPHERE(jump);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void do_utfreadchar16(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character. TMP1 contains the first byte
+of the character (>= 0xc0). Return value in TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+/* Searching for the first zero. */
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
+jump = JUMP(SLJIT_NOT_ZERO);
+/* Two byte sequence. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO);
+/* This code runs only in 8 bit mode. No need to shift the value. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+/* Three byte sequence. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void do_utfreadtype8(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
+of the character (>= 0xc0). Return value in TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_jump *compare;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
+jump = JUMP(SLJIT_NOT_ZERO);
+/* Two byte sequence. */
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
+/* The upper 5 bits are known at this point. */
+compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(compare);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+/* We only have types for characters less than 256. */
+JUMPHERE(jump);
+OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+
+/* UCD_BLOCK_SIZE must be 128 (see the assert below). */
+#define UCD_BLOCK_MASK 127
+#define UCD_BLOCK_SHIFT 7
+
+static void do_getucd(compiler_common *common)
+{
+/* Search the UCD record for the character comes in TMP1.
+Returns chartype in TMP1 and UCD offset in TMP2. */
+DEFINE_COMPILER;
+
+SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
+OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#endif /* SUPPORT_UNICODE */
+
+static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, sljit_u32 overall_options)
+{
+DEFINE_COMPILER;
+struct sljit_label *mainloop;
+struct sljit_label *newlinelabel = NULL;
+struct sljit_jump *start;
+struct sljit_jump *end = NULL;
+struct sljit_jump *end2 = NULL;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_jump *singlechar;
+#endif
+jump_list *newline = NULL;
+BOOL newlinecheck = FALSE;
+BOOL readuchar = FALSE;
+
+if (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0)
+ && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
+ newlinecheck = TRUE;
+
+SLJIT_ASSERT(common->forced_quit_label == NULL);
+
+if ((overall_options & PCRE2_FIRSTLINE) != 0)
+ {
+ /* Search for the end of the first line. */
+ SLJIT_ASSERT(common->match_end_ptr != 0);
+ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ mainloop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
+ CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
+ JUMPHERE(end);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+ else
+ {
+ end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ mainloop = LABEL();
+ /* Continual stores does not cause data dependency. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
+ check_newlinechar(common, common->nltype, &newline, TRUE);
+ CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);
+ JUMPHERE(end);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
+ set_jumps(newline, LABEL());
+ }
+
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ }
+else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0)
+ {
+ /* Check whether offset limit is set and valid. */
+ SLJIT_ASSERT(common->match_end_ptr != 0);
+
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit));
+ OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
+ end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET);
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+#if PCRE2_CODE_UNIT_WIDTH == 16
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);
+#endif
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
+ end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
+ JUMPHERE(end2);
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
+ add_jump(compiler, &common->forced_quit, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0));
+ JUMPHERE(end);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0);
+ }
+
+start = JUMP(SLJIT_JUMP);
+
+if (newlinecheck)
+ {
+ newlinelabel = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ end2 = JUMP(SLJIT_JUMP);
+ }
+
+mainloop = LABEL();
+
+/* Increasing the STR_PTR here requires one less jump in the most common case. */
+#ifdef SUPPORT_UNICODE
+if (common->utf) readuchar = TRUE;
+#endif
+if (newlinecheck) readuchar = TRUE;
+
+if (readuchar)
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+if (newlinecheck)
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+#if PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
+JUMPHERE(start);
+
+if (newlinecheck)
+ {
+ JUMPHERE(end);
+ JUMPHERE(end2);
+ }
+
+return mainloop;
+}
+
+#define MAX_N_CHARS 16
+#define MAX_DIFF_CHARS 6
+
+static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, PCRE2_UCHAR *chars)
+{
+PCRE2_UCHAR i, len;
+
+len = chars[0];
+if (len == 255)
+ return;
+
+if (len == 0)
+ {
+ chars[0] = 1;
+ chars[1] = chr;
+ return;
+ }
+
+for (i = len; i > 0; i--)
+ if (chars[i] == chr)
+ return;
+
+if (len >= MAX_DIFF_CHARS - 1)
+ {
+ chars[0] = 255;
+ return;
+ }
+
+len++;
+chars[len] = chr;
+chars[0] = len;
+}
+
+static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *chars, int max_chars, sljit_u32 *rec_count)
+{
+/* Recursive function, which scans prefix literals. */
+BOOL last, any, class, caseless;
+int len, repeat, len_save, consumed = 0;
+sljit_u32 chr; /* Any unicode character. */
+sljit_u8 *bytes, *bytes_end, byte;
+PCRE2_SPTR alternative, cc_save, oc;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+PCRE2_UCHAR othercase[8];
+#elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
+PCRE2_UCHAR othercase[2];
+#else
+PCRE2_UCHAR othercase[1];
+#endif
+
+repeat = 1;
+while (TRUE)
+ {
+ if (*rec_count == 0)
+ return 0;
+ (*rec_count)--;
+
+ last = TRUE;
+ any = FALSE;
+ class = FALSE;
+ caseless = FALSE;
+
+ switch (*cc)
+ {
+ case OP_CHARI:
+ caseless = TRUE;
+ case OP_CHAR:
+ last = FALSE;
+ cc++;
+ break;
+
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ /* Zero width assertions. */
+ cc++;
+ continue;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ cc = bracketend(cc);
+ continue;
+
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ caseless = TRUE;
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ cc++;
+ break;
+
+ case OP_EXACTI:
+ caseless = TRUE;
+ case OP_EXACT:
+ repeat = GET2(cc, 1);
+ last = FALSE;
+ cc += 1 + IMM2_SIZE;
+ break;
+
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ caseless = TRUE;
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ len = 1;
+ cc++;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
+#endif
+ max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count);
+ if (max_chars == 0)
+ return consumed;
+ last = FALSE;
+ break;
+
+ case OP_KET:
+ cc += 1 + LINK_SIZE;
+ continue;
+
+ case OP_ALT:
+ cc += GET(cc, 1);
+ continue;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ alternative = cc + GET(cc, 1);
+ while (*alternative == OP_ALT)
+ {
+ max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count);
+ if (max_chars == 0)
+ return consumed;
+ alternative += GET(alternative, 1);
+ }
+
+ if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
+ cc += IMM2_SIZE;
+ cc += 1 + LINK_SIZE;
+ continue;
+
+ case OP_CLASS:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE))
+ return consumed;
+#endif
+ class = TRUE;
+ break;
+
+ case OP_NCLASS:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf) return consumed;
+#endif
+ class = TRUE;
+ break;
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ cc += GET(cc, 1);
+ break;
+#endif
+
+ case OP_DIGIT:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
+ return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+ case OP_WHITESPACE:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE))
+ return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+ case OP_WORDCHAR:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE))
+ return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+ case OP_NOT:
+ case OP_NOTI:
+ cc++;
+ /* Fall through. */
+ case OP_NOT_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+#ifdef SUPPORT_UNICODE
+ case OP_NOTPROP:
+ case OP_PROP:
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ cc += 1 + 2;
+ break;
+#endif
+
+ case OP_TYPEEXACT:
+ repeat = GET2(cc, 1);
+ cc += 1 + IMM2_SIZE;
+ continue;
+
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ repeat = GET2(cc, 1);
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+
+ default:
+ return consumed;
+ }
+
+ if (any)
+ {
+ do
+ {
+ chars[0] = 255;
+
+ consumed++;
+ if (--max_chars == 0)
+ return consumed;
+ chars += MAX_DIFF_CHARS;
+ }
+ while (--repeat > 0);
+
+ repeat = 1;
+ continue;
+ }
+
+ if (class)
+ {
+ bytes = (sljit_u8*) (cc + 1);
+ cc += 1 + 32 / sizeof(PCRE2_UCHAR);
+
+ switch (*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPOSSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSQUERY:
+ max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count);
+ if (max_chars == 0)
+ return consumed;
+ break;
+
+ default:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ repeat = GET2(cc, 1);
+ if (repeat <= 0)
+ return consumed;
+ break;
+ }
+
+ do
+ {
+ if (bytes[31] & 0x80)
+ chars[0] = 255;
+ else if (chars[0] != 255)
+ {
+ bytes_end = bytes + 32;
+ chr = 0;
+ do
+ {
+ byte = *bytes++;
+ SLJIT_ASSERT((chr & 0x7) == 0);
+ if (byte == 0)
+ chr += 8;
+ else
+ {
+ do
+ {
+ if ((byte & 0x1) != 0)
+ add_prefix_char(chr, chars);
+ byte >>= 1;
+ chr++;
+ }
+ while (byte != 0);
+ chr = (chr + 7) & ~7;
+ }
+ }
+ while (chars[0] != 255 && bytes < bytes_end);
+ bytes = bytes_end - 32;
+ }
+
+ consumed++;
+ if (--max_chars == 0)
+ return consumed;
+ chars += MAX_DIFF_CHARS;
+ }
+ while (--repeat > 0);
+
+ switch (*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPOSSTAR:
+ return consumed;
+
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSQUERY:
+ cc++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE))
+ return consumed;
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+ }
+
+ repeat = 1;
+ continue;
+ }
+
+ len = 1;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
+#endif
+
+ if (caseless && char_has_othercase(common, cc))
+ {
+#ifdef SUPPORT_UNICODE
+ if (common->utf)
+ {
+ GETCHAR(chr, cc);
+ if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)
+ return consumed;
+ }
+ else
+#endif
+ {
+ chr = *cc;
+ othercase[0] = TABLE_GET(chr, common->fcc, chr);
+ }
+ }
+ else
+ {
+ caseless = FALSE;
+ othercase[0] = 0; /* Stops compiler warning - PH */
+ }
+
+ len_save = len;
+ cc_save = cc;
+ while (TRUE)
+ {
+ oc = othercase;
+ do
+ {
+ chr = *cc;
+ add_prefix_char(*cc, chars);
+
+ if (caseless)
+ add_prefix_char(*oc, chars);
+
+ len--;
+ consumed++;
+ if (--max_chars == 0)
+ return consumed;
+ chars += MAX_DIFF_CHARS;
+ cc++;
+ oc++;
+ }
+ while (len > 0);
+
+ if (--repeat == 0)
+ break;
+
+ len = len_save;
+ cc = cc_save;
+ }
+
+ repeat = 1;
+ if (last)
+ return consumed;
+ }
+}
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+static sljit_s32 character_to_int32(PCRE2_UCHAR chr)
+{
+sljit_s32 value = (sljit_s32)chr;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define SSE2_COMPARE_TYPE_INDEX 0
+return (value << 24) | (value << 16) | (value << 8) | value;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+#define SSE2_COMPARE_TYPE_INDEX 1
+return (value << 16) | value;
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+#define SSE2_COMPARE_TYPE_INDEX 2
+return value;
+#else
+#error "Unsupported unit width"
+#endif
+}
+
+static SLJIT_INLINE void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *quit[3];
+struct sljit_jump *nomatch;
+sljit_u8 instruction[8];
+sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
+sljit_s32 tmp2_ind = sljit_get_register_index(TMP2);
+sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
+BOOL load_twice = FALSE;
+PCRE2_UCHAR bit;
+
+bit = char1 ^ char2;
+if (!is_powerof2(bit))
+ bit = 0;
+
+if ((char1 != char2) && bit == 0)
+ load_twice = TRUE;
+
+quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+/* First part (unaligned start) */
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
+
+SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1);
+
+/* MOVD xmm, r/m32 */
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+instruction[2] = 0x6e;
+instruction[3] = 0xc0 | (2 << 3) | tmp1_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (char1 != char2)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
+
+ /* MOVD xmm, r/m32 */
+ instruction[3] = 0xc0 | (3 << 3) | tmp1_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+/* PSHUFD xmm1, xmm2/m128, imm8 */
+instruction[2] = 0x70;
+instruction[3] = 0xc0 | (2 << 3) | 2;
+instruction[4] = 0;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+if (char1 != char2)
+ {
+ /* PSHUFD xmm1, xmm2/m128, imm8 */
+ instruction[3] = 0xc0 | (3 << 3) | 3;
+ instruction[4] = 0;
+ sljit_emit_op_custom(compiler, instruction, 5);
+ }
+
+OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 0xf);
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
+
+/* MOVDQA xmm1, xmm2/m128 */
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+if (str_ptr_ind < 8)
+ {
+ instruction[2] = 0x6f;
+ instruction[3] = (0 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+
+ if (load_twice)
+ {
+ instruction[3] = (1 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+ }
+else
+ {
+ instruction[1] = 0x41;
+ instruction[2] = 0x0f;
+ instruction[3] = 0x6f;
+ instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
+ sljit_emit_op_custom(compiler, instruction, 5);
+
+ if (load_twice)
+ {
+ instruction[4] = (1 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 5);
+ }
+ instruction[1] = 0x0f;
+ }
+
+#else
+
+instruction[2] = 0x6f;
+instruction[3] = (0 << 3) | str_ptr_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (load_twice)
+ {
+ instruction[3] = (1 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+#endif
+
+if (bit != 0)
+ {
+ /* POR xmm1, xmm2/m128 */
+ instruction[2] = 0xeb;
+ instruction[3] = 0xc0 | (0 << 3) | 3;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+/* PCMPEQB/W/D xmm1, xmm2/m128 */
+instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
+instruction[3] = 0xc0 | (0 << 3) | 2;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (load_twice)
+ {
+ instruction[3] = 0xc0 | (1 << 3) | 3;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+/* PMOVMSKB reg, xmm */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (load_twice)
+ {
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0);
+ instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
+ sljit_emit_op_custom(compiler, instruction, 4);
+
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0);
+ }
+
+OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+/* BSF r32, r/m32 */
+instruction[0] = 0x0f;
+instruction[1] = 0xbc;
+instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
+sljit_emit_op_custom(compiler, instruction, 3);
+
+nomatch = JUMP(SLJIT_ZERO);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+quit[1] = JUMP(SLJIT_JUMP);
+
+JUMPHERE(nomatch);
+
+start = LABEL();
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
+quit[2] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+/* Second part (aligned) */
+
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+
+/* MOVDQA xmm1, xmm2/m128 */
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+if (str_ptr_ind < 8)
+ {
+ instruction[2] = 0x6f;
+ instruction[3] = (0 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+
+ if (load_twice)
+ {
+ instruction[3] = (1 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+ }
+else
+ {
+ instruction[1] = 0x41;
+ instruction[2] = 0x0f;
+ instruction[3] = 0x6f;
+ instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
+ sljit_emit_op_custom(compiler, instruction, 5);
+
+ if (load_twice)
+ {
+ instruction[4] = (1 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 5);
+ }
+ instruction[1] = 0x0f;
+ }
+
+#else
+
+instruction[2] = 0x6f;
+instruction[3] = (0 << 3) | str_ptr_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (load_twice)
+ {
+ instruction[3] = (1 << 3) | str_ptr_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+#endif
+
+if (bit != 0)
+ {
+ /* POR xmm1, xmm2/m128 */
+ instruction[2] = 0xeb;
+ instruction[3] = 0xc0 | (0 << 3) | 3;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+/* PCMPEQB/W/D xmm1, xmm2/m128 */
+instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
+instruction[3] = 0xc0 | (0 << 3) | 2;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (load_twice)
+ {
+ instruction[3] = 0xc0 | (1 << 3) | 3;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+/* PMOVMSKB reg, xmm */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (load_twice)
+ {
+ instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
+ sljit_emit_op_custom(compiler, instruction, 4);
+
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ }
+
+/* BSF r32, r/m32 */
+instruction[0] = 0x0f;
+instruction[1] = 0xbc;
+instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
+sljit_emit_op_custom(compiler, instruction, 3);
+
+JUMPTO(SLJIT_ZERO, start);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+
+start = LABEL();
+SET_LABEL(quit[0], start);
+SET_LABEL(quit[1], start);
+SET_LABEL(quit[2], start);
+}
+
+#undef SSE2_COMPARE_TYPE_INDEX
+
+#endif
+
+static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *quit;
+struct sljit_jump *found;
+PCRE2_UCHAR mask;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_label *utf_start = NULL;
+struct sljit_jump *utf_quit = NULL;
+#endif
+BOOL has_match_end = (common->match_end_ptr != 0);
+
+if (offset > 0)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
+
+if (has_match_end)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
+
+ OP2(SLJIT_ADD, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, SLJIT_IMM, IN_UCHARS(offset + 1));
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+ if (sljit_x86_is_cmov_available())
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_END, 0, TMP3, 0);
+ sljit_x86_emit_cmov(compiler, SLJIT_GREATER, STR_END, TMP3, 0);
+ }
+#endif
+ {
+ quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP3, 0);
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+ JUMPHERE(quit);
+ }
+ }
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf && offset > 0)
+ utf_start = LABEL();
+#endif
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+/* SSE2 accelerated first character search. */
+
+if (sljit_x86_is_sse2_available())
+ {
+ fast_forward_first_char2_sse2(common, char1, char2);
+
+ SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0);
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ {
+ /* In complete mode, we don't need to run a match when STR_PTR == STR_END. */
+ SLJIT_ASSERT(common->forced_quit_label == NULL);
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
+ add_jump(compiler, &common->forced_quit, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf && offset > 0)
+ {
+ SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
+
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
+#else
+#error "Unknown code width"
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+#endif
+
+ if (offset > 0)
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
+ }
+ else if (sljit_x86_is_cmov_available())
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
+ sljit_x86_emit_cmov(compiler, SLJIT_GREATER_EQUAL, STR_PTR, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0);
+ }
+ else
+ {
+ quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0);
+ JUMPHERE(quit);
+ }
+
+ if (has_match_end)
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+ return;
+ }
+
+#endif
+
+quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+start = LABEL();
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+if (char1 == char2)
+ found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);
+else
+ {
+ mask = char1 ^ char2;
+ if (is_powerof2(mask))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
+ found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask);
+ }
+ else
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char1);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char2);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ found = JUMP(SLJIT_NOT_ZERO);
+ }
+ }
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, start);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf && offset > 0)
+ utf_quit = JUMP(SLJIT_JUMP);
+#endif
+
+JUMPHERE(found);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf && offset > 0)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
+#else
+#error "Unknown code width"
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ JUMPHERE(utf_quit);
+ }
+#endif
+
+JUMPHERE(quit);
+
+if (has_match_end)
+ {
+ quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ if (offset > 0)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
+ JUMPHERE(quit);
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+ }
+
+if (offset > 0)
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
+}
+
+static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *quit;
+struct sljit_jump *match;
+/* bytes[0] represent the number of characters between 0
+and MAX_N_BYTES - 1, 255 represents any character. */
+PCRE2_UCHAR chars[MAX_N_CHARS * MAX_DIFF_CHARS];
+sljit_s32 offset;
+PCRE2_UCHAR mask;
+PCRE2_UCHAR *char_set, *char_set_end;
+int i, max, from;
+int range_right = -1, range_len;
+sljit_u8 *update_table = NULL;
+BOOL in_range;
+sljit_u32 rec_count;
+
+for (i = 0; i < MAX_N_CHARS; i++)
+ chars[i * MAX_DIFF_CHARS] = 0;
+
+rec_count = 10000;
+max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count);
+
+if (max < 1)
+ return FALSE;
+
+in_range = FALSE;
+/* Prevent compiler "uninitialized" warning */
+from = 0;
+range_len = 4 /* minimum length */ - 1;
+for (i = 0; i <= max; i++)
+ {
+ if (in_range && (i - from) > range_len && (chars[(i - 1) * MAX_DIFF_CHARS] < 255))
+ {
+ range_len = i - from;
+ range_right = i - 1;
+ }
+
+ if (i < max && chars[i * MAX_DIFF_CHARS] < 255)
+ {
+ SLJIT_ASSERT(chars[i * MAX_DIFF_CHARS] > 0);
+ if (!in_range)
+ {
+ in_range = TRUE;
+ from = i;
+ }
+ }
+ else
+ in_range = FALSE;
+ }
+
+if (range_right >= 0)
+ {
+ update_table = (sljit_u8 *)allocate_read_only_data(common, 256);
+ if (update_table == NULL)
+ return TRUE;
+ memset(update_table, IN_UCHARS(range_len), 256);
+
+ for (i = 0; i < range_len; i++)
+ {
+ char_set = chars + ((range_right - i) * MAX_DIFF_CHARS);
+ SLJIT_ASSERT(char_set[0] > 0 && char_set[0] < 255);
+ char_set_end = char_set + char_set[0];
+ char_set++;
+ while (char_set <= char_set_end)
+ {
+ if (update_table[(*char_set) & 0xff] > IN_UCHARS(i))
+ update_table[(*char_set) & 0xff] = IN_UCHARS(i);
+ char_set++;
+ }
+ }
+ }
+
+offset = -1;
+/* Scan forward. */
+for (i = 0; i < max; i++)
+ {
+ if (offset == -1)
+ {
+ if (chars[i * MAX_DIFF_CHARS] <= 2)
+ offset = i;
+ }
+ else if (chars[offset * MAX_DIFF_CHARS] == 2 && chars[i * MAX_DIFF_CHARS] <= 2)
+ {
+ if (chars[i * MAX_DIFF_CHARS] == 1)
+ offset = i;
+ else
+ {
+ mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2];
+ if (!is_powerof2(mask))
+ {
+ mask = chars[i * MAX_DIFF_CHARS + 1] ^ chars[i * MAX_DIFF_CHARS + 2];
+ if (is_powerof2(mask))
+ offset = i;
+ }
+ }
+ }
+ }
+
+if (range_right < 0)
+ {
+ if (offset < 0)
+ return FALSE;
+ SLJIT_ASSERT(chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2);
+ /* Works regardless the value is 1 or 2. */
+ mask = chars[offset * MAX_DIFF_CHARS + chars[offset * MAX_DIFF_CHARS]];
+ fast_forward_first_char2(common, chars[offset * MAX_DIFF_CHARS + 1], mask, offset);
+ return TRUE;
+ }
+
+if (range_right == offset)
+ offset = -1;
+
+SLJIT_ASSERT(offset == -1 || (chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2));
+
+max -= 1;
+SLJIT_ASSERT(max > 0);
+if (common->match_end_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
+ OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+ quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0);
+ OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
+ JUMPHERE(quit);
+ }
+else
+ OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+
+SLJIT_ASSERT(range_right >= 0);
+
+#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
+#endif
+
+start = LABEL();
+quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+#if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
+#else
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
+#endif
+
+#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
+#else
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
+
+if (offset >= 0)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+ if (chars[offset * MAX_DIFF_CHARS] == 1)
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1], start);
+ else
+ {
+ mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2];
+ if (is_powerof2(mask))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1] | mask, start);
+ }
+ else
+ {
+ match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1]);
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 2], start);
+ JUMPHERE(match);
+ }
+ }
+ }
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf && offset != 0)
+ {
+ if (offset < 0)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+ else
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, start);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, start);
+#else
+#error "Unknown code width"
+#endif
+ if (offset < 0)
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+#endif
+
+if (offset >= 0)
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+JUMPHERE(quit);
+
+if (common->match_end_ptr != 0)
+ {
+ if (range_right >= 0)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+ if (range_right >= 0)
+ {
+ quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(quit);
+ }
+ }
+else
+ OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+return TRUE;
+}
+
+#undef MAX_N_CHARS
+
+static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, PCRE2_UCHAR first_char, BOOL caseless)
+{
+PCRE2_UCHAR oc;
+
+oc = first_char;
+if (caseless)
+ {
+ oc = TABLE_GET(first_char, common->fcc, first_char);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ if (first_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(first_char);
+#endif
+ }
+
+fast_forward_first_char2(common, first_char, oc, 0);
+}
+
+static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *lastchar;
+struct sljit_jump *firstchar;
+struct sljit_jump *quit;
+struct sljit_jump *foundcr = NULL;
+struct sljit_jump *notfoundnl;
+jump_list *newline = NULL;
+
+if (common->match_end_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ }
+
+if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL);
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+ loop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
+ CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+
+ JUMPHERE(quit);
+ JUMPHERE(firstchar);
+ JUMPHERE(lastchar);
+
+ if (common->match_end_ptr != 0)
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+ return;
+ }
+
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+skip_char_back(common);
+
+loop = LABEL();
+common->ff_newline_shortcut = loop;
+
+read_char_range(common, common->nlmin, common->nlmax, TRUE);
+lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+check_newlinechar(common, common->nltype, &newline, FALSE);
+set_jumps(newline, loop);
+
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ {
+ quit = JUMP(SLJIT_JUMP);
+ JUMPHERE(foundcr);
+ notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(notfoundnl);
+ JUMPHERE(quit);
+ }
+JUMPHERE(lastchar);
+JUMPHERE(firstchar);
+
+if (common->match_end_ptr != 0)
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+}
+
+static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
+
+static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_u8 *start_bits)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *quit;
+struct sljit_jump *found = NULL;
+jump_list *matches = NULL;
+#if PCRE2_CODE_UNIT_WIDTH != 8
+struct sljit_jump *jump;
+#endif
+
+if (common->match_end_ptr != 0)
+ {
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ }
+
+start = LABEL();
+quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UNICODE
+if (common->utf)
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#endif
+
+if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
+ JUMPHERE(jump);
+#endif
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ found = JUMP(SLJIT_NOT_ZERO);
+ }
+
+#ifdef SUPPORT_UNICODE
+if (common->utf)
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+ CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+if (common->utf)
+ {
+ CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
+#endif /* SUPPORT_UNICODE */
+JUMPTO(SLJIT_JUMP, start);
+if (found != NULL)
+ JUMPHERE(found);
+if (matches != NULL)
+ set_jumps(matches, LABEL());
+JUMPHERE(quit);
+
+if (common->match_end_ptr != 0)
+ OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
+}
+
+static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *toolong;
+struct sljit_jump *alreadyfound;
+struct sljit_jump *found;
+struct sljit_jump *foundoc = NULL;
+struct sljit_jump *notfound;
+sljit_u32 oc, bit;
+
+SLJIT_ASSERT(common->req_char_ptr != 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
+OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_CU_MAX);
+toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0);
+alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
+
+if (has_firstchar)
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+else
+ OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
+
+loop = LABEL();
+notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+oc = req_char;
+if (caseless)
+ {
+ oc = TABLE_GET(req_char, common->fcc, req_char);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ if (req_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(req_char);
+#endif
+ }
+if (req_char == oc)
+ found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+else
+ {
+ bit = req_char ^ oc;
+ if (is_powerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
+ }
+ else
+ {
+ found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+ foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
+ }
+ }
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_JUMP, loop);
+
+JUMPHERE(found);
+if (foundoc)
+ JUMPHERE(foundoc);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);
+JUMPHERE(alreadyfound);
+JUMPHERE(toolong);
+return notfound;
+}
+
+static void do_revertframes(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *mainloop;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
+GET_LOCAL_BASE(TMP3, 0, 0);
+
+/* Drop frames until we reach STACK_TOP. */
+mainloop = LABEL();
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
+jump = JUMP(SLJIT_SIG_LESS_EQUAL);
+
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
+JUMPTO(SLJIT_JUMP, mainloop);
+
+JUMPHERE(jump);
+jump = JUMP(SLJIT_SIG_LESS);
+/* End of dropping frames. */
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
+JUMPTO(SLJIT_JUMP, mainloop);
+}
+
+static void check_wordboundary(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *skipread;
+jump_list *skipread_list = NULL;
+#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE
+struct sljit_jump *jump;
+#endif
+
+SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+/* Get type of the previous char, and put it to LOCALS1. */
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0);
+skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
+skip_char_back(common);
+check_start_used_ptr(common);
+read_char(common);
+
+/* Testing char type. */
+#ifdef SUPPORT_UNICODE
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ JUMPHERE(jump);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
+ }
+else
+#endif
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UNICODE
+ /* Here LOCALS1 has already been zeroed. */
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UNICODE
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ }
+JUMPHERE(skipread);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+check_str_end(common, &skipread_list);
+peek_char(common, READ_CHAR_MAX);
+
+/* Testing char type. This is a code duplication. */
+#ifdef SUPPORT_UNICODE
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ JUMPHERE(jump);
+ }
+else
+#endif
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ /* TMP2 may be destroyed by peek_char. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UNICODE
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif
+ OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UNICODE
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ }
+set_jumps(skipread_list, LABEL());
+
+OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+}
+
+static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
+{
+/* May destroy TMP1. */
+DEFINE_COMPILER;
+int ranges[MAX_RANGE_SIZE];
+sljit_u8 bit, cbit, all;
+int i, byte, length = 0;
+
+bit = bits[0] & 0x1;
+/* All bits will be zero or one (since bit is zero or one). */
+all = -bit;
+
+for (i = 0; i < 256; )
+ {
+ byte = i >> 3;
+ if ((i & 0x7) == 0 && bits[byte] == all)
+ i += 8;
+ else
+ {
+ cbit = (bits[byte] >> (i & 0x7)) & 0x1;
+ if (cbit != bit)
+ {
+ if (length >= MAX_RANGE_SIZE)
+ return FALSE;
+ ranges[length] = i;
+ length++;
+ bit = cbit;
+ all = -cbit;
+ }
+ i++;
+ }
+ }
+
+if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
+ {
+ if (length >= MAX_RANGE_SIZE)
+ return FALSE;
+ ranges[length] = 256;
+ length++;
+ }
+
+if (length < 0 || length > 4)
+ return FALSE;
+
+bit = bits[0] & 0x1;
+if (invert) bit ^= 0x1;
+
+/* No character is accepted. */
+if (length == 0 && bit == 0)
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+
+switch(length)
+ {
+ case 0:
+ /* When bit != 0, all characters are accepted. */
+ return TRUE;
+
+ case 1:
+ add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+ return TRUE;
+
+ case 2:
+ if (ranges[0] + 1 != ranges[1])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+ return TRUE;
+
+ case 3:
+ if (bit != 0)
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
+ if (ranges[0] + 1 != ranges[1])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+ return TRUE;
+ }
+
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
+ if (ranges[1] + 1 != ranges[2])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
+ return TRUE;
+
+ case 4:
+ if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
+ && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
+ && (ranges[1] & (ranges[2] - ranges[0])) == 0
+ && is_powerof2(ranges[2] - ranges[0]))
+ {
+ SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
+ if (ranges[2] + 1 != ranges[3])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
+ return TRUE;
+ }
+
+ if (bit != 0)
+ {
+ i = 0;
+ if (ranges[0] + 1 != ranges[1])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ i = ranges[0];
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+
+ if (ranges[2] + 1 != ranges[3])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
+ return TRUE;
+ }
+
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
+ if (ranges[1] + 1 != ranges[2])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ return TRUE;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return FALSE;
+ }
+}
+
+static void check_anynewline(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+#if PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+#endif
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ }
+#endif
+#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
+OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_hspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+#if PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+#endif
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ }
+#endif
+#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
+OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_vspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+#if PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utf)
+ {
+#endif
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ }
+#endif
+#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
+OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define CHAR1 STR_END
+#define CHAR2 STACK_TOP
+
+static void do_casefulcmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define LCC_TABLE STACK_LIMIT
+
+static void do_caselesscmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
+OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+#if PCRE2_CODE_UNIT_WIDTH != 8
+jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+JUMPHERE(jump);
+jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+JUMPHERE(jump);
+#endif
+jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#undef LCC_TABLE
+#undef CHAR1
+#undef CHAR2
+
+#if defined SUPPORT_UNICODE
+
+static PCRE2_SPTR SLJIT_CALL do_utf_caselesscmp(PCRE2_SPTR src1, jit_arguments *args, PCRE2_SPTR end1)
+{
+/* This function would be ineffective to do in JIT level. */
+sljit_u32 c1, c2;
+PCRE2_SPTR src2 = args->startchar_ptr;
+PCRE2_SPTR end2 = args->end;
+const ucd_record *ur;
+const sljit_u32 *pp;
+
+while (src1 < end1)
+ {
+ if (src2 >= end2)
+ return (PCRE2_SPTR)1;
+ GETCHARINC(c1, src1);
+ GETCHARINC(c2, src2);
+ ur = GET_UCD(c2);
+ if (c1 != c2 && c1 != c2 + ur->other_case)
+ {
+ pp = PRIV(ucd_caseless_sets) + ur->caseset;
+ for (;;)
+ {
+ if (c1 < *pp) return NULL;
+ if (c1 == *pp++) break;
+ }
+ }
+ }
+return src2;
+}
+
+#endif /* SUPPORT_UNICODE */
+
+static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc,
+ compare_context *context, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+unsigned int othercasebit = 0;
+PCRE2_SPTR othercasechar = NULL;
+#ifdef SUPPORT_UNICODE
+int utflength;
+#endif
+
+if (caseless && char_has_othercase(common, cc))
+ {
+ othercasebit = char_get_othercase_bit(common, cc);
+ SLJIT_ASSERT(othercasebit);
+ /* Extracting bit difference info. */
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ othercasechar = cc + (othercasebit >> 8);
+ othercasebit &= 0xff;
+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ /* Note that this code only handles characters in the BMP. If there
+ ever are characters outside the BMP whose othercase differs in only one
+ bit from itself (there currently are none), this code will need to be
+ revised for PCRE2_CODE_UNIT_WIDTH == 32. */
+ othercasechar = cc + (othercasebit >> 9);
+ if ((othercasebit & 0x100) != 0)
+ othercasebit = (othercasebit & 0xff) << 8;
+ else
+ othercasebit &= 0xff;
+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
+ }
+
+if (context->sourcereg == -1)
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
+ context->sourcereg = TMP2;
+ }
+
+#ifdef SUPPORT_UNICODE
+utflength = 1;
+if (common->utf && HAS_EXTRALEN(*cc))
+ utflength += GET_EXTRALEN(*cc);
+
+do
+ {
+#endif
+
+ context->length -= IN_UCHARS(1);
+#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
+
+ /* Unaligned read is supported. */
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ context->c.asuchars[context->ucharptr] = *cc | othercasebit;
+ context->oc.asuchars[context->ucharptr] = othercasebit;
+ }
+ else
+ {
+ context->c.asuchars[context->ucharptr] = *cc;
+ context->oc.asuchars[context->ucharptr] = 0;
+ }
+ context->ucharptr++;
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
+#else
+ if (context->ucharptr >= 2 || context->length == 0)
+#endif
+ {
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ else if (context->length >= 1)
+ OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ switch(context->ucharptr)
+ {
+ case 4 / sizeof(PCRE2_UCHAR):
+ if (context->oc.asint != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
+ break;
+
+ case 2 / sizeof(PCRE2_UCHAR):
+ if (context->oc.asushort != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
+ break;
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ case 1:
+ if (context->oc.asbyte != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
+ break;
+#endif
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ context->ucharptr = 0;
+ }
+
+#else
+
+ /* Unaligned read is unsupported or in 32 bit mode. */
+ if (context->length >= 1)
+ OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
+
+#endif
+
+ cc++;
+#ifdef SUPPORT_UNICODE
+ utflength--;
+ }
+while (utflength > 0);
+#endif
+
+return cc;
+}
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+
+#define SET_TYPE_OFFSET(value) \
+ if ((value) != typeoffset) \
+ { \
+ if ((value) < typeoffset) \
+ OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
+ else \
+ OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
+ } \
+ typeoffset = (value);
+
+#define SET_CHAR_OFFSET(value) \
+ if ((value) != charoffset) \
+ { \
+ if ((value) < charoffset) \
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
+ else \
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
+ } \
+ charoffset = (value);
+
+static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr);
+
+static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+jump_list *found = NULL;
+jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
+sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
+struct sljit_jump *jump = NULL;
+PCRE2_SPTR ccbegin;
+int compares, invertcmp, numberofcmps;
+#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
+BOOL utf = common->utf;
+#endif
+
+#ifdef SUPPORT_UNICODE
+BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
+BOOL charsaved = FALSE;
+int typereg = TMP1;
+const sljit_u32 *other_cases;
+sljit_uw typeoffset;
+#endif
+
+/* Scanning the necessary info. */
+cc++;
+ccbegin = cc;
+compares = 0;
+
+if (cc[-1] & XCL_MAP)
+ {
+ min = 0;
+ cc += 32 / sizeof(PCRE2_UCHAR);
+ }
+
+while (*cc != XCL_END)
+ {
+ compares++;
+ if (*cc == XCL_SINGLE)
+ {
+ cc ++;
+ GETCHARINCTEST(c, cc);
+ if (c > max) max = c;
+ if (c < min) min = c;
+#ifdef SUPPORT_UNICODE
+ needschar = TRUE;
+#endif
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc ++;
+ GETCHARINCTEST(c, cc);
+ if (c < min) min = c;
+ GETCHARINCTEST(c, cc);
+ if (c > max) max = c;
+#ifdef SUPPORT_UNICODE
+ needschar = TRUE;
+#endif
+ }
+#ifdef SUPPORT_UNICODE
+ else
+ {
+ SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
+ cc++;
+ if (*cc == PT_CLIST)
+ {
+ other_cases = PRIV(ucd_caseless_sets) + cc[1];
+ while (*other_cases != NOTACHAR)
+ {
+ if (*other_cases > max) max = *other_cases;
+ if (*other_cases < min) min = *other_cases;
+ other_cases++;
+ }
+ }
+ else
+ {
+ max = READ_CHAR_MAX;
+ min = 0;
+ }
+
+ switch(*cc)
+ {
+ case PT_ANY:
+ /* Any either accepts everything or ignored. */
+ if (cc[-1] == XCL_PROP)
+ {
+ compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE);
+ if (list == backtracks)
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ return;
+ }
+ break;
+
+ case PT_LAMP:
+ case PT_GC:
+ case PT_PC:
+ case PT_ALNUM:
+ needstype = TRUE;
+ break;
+
+ case PT_SC:
+ needsscript = TRUE;
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ case PT_WORD:
+ case PT_PXGRAPH:
+ case PT_PXPRINT:
+ case PT_PXPUNCT:
+ needstype = TRUE;
+ needschar = TRUE;
+ break;
+
+ case PT_CLIST:
+ case PT_UCNC:
+ needschar = TRUE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ cc += 2;
+ }
+#endif
+ }
+SLJIT_ASSERT(compares > 0);
+
+/* We are not necessary in utf mode even in 8 bit mode. */
+cc = ccbegin;
+read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
+
+if ((cc[-1] & XCL_HASPROP) == 0)
+ {
+ if ((cc[-1] & XCL_MAP) != 0)
+ {
+ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ if (!check_class_ranges(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found))
+ {
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
+ }
+
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(jump);
+
+ cc += 32 / sizeof(PCRE2_UCHAR);
+ }
+ else
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
+ add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min));
+ }
+ }
+else if ((cc[-1] & XCL_MAP) != 0)
+ {
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+#ifdef SUPPORT_UNICODE
+ charsaved = TRUE;
+#endif
+ if (!check_class_ranges(common, (const sljit_u8 *)cc, FALSE, TRUE, list))
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ jump = NULL;
+ if (common->utf)
+#endif
+ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
+
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf)
+#endif
+ JUMPHERE(jump);
+ }
+
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ cc += 32 / sizeof(PCRE2_UCHAR);
+ }
+
+#ifdef SUPPORT_UNICODE
+if (needstype || needsscript)
+ {
+ if (needschar && !charsaved)
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+
+ OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+ OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
+ OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
+
+ /* Before anything else, we deal with scripts. */
+ if (needsscript)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+
+ ccbegin = cc;
+
+ while (*cc != XCL_END)
+ {
+ if (*cc == XCL_SINGLE)
+ {
+ cc ++;
+ GETCHARINCTEST(c, cc);
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc ++;
+ GETCHARINCTEST(c, cc);
+ GETCHARINCTEST(c, cc);
+ }
+ else
+ {
+ SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
+ cc++;
+ if (*cc == PT_SC)
+ {
+ compares--;
+ invertcmp = (compares == 0 && list != backtracks);
+ if (cc[-1] == XCL_NOTPROP)
+ invertcmp ^= 0x1;
+ jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]);
+ add_jump(compiler, compares > 0 ? list : backtracks, jump);
+ }
+ cc += 2;
+ }
+ }
+
+ cc = ccbegin;
+ }
+
+ if (needschar)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ }
+
+ if (needstype)
+ {
+ if (!needschar)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+ }
+ else
+ {
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+ typereg = RETURN_ADDR;
+ }
+ }
+ }
+#endif
+
+/* Generating code. */
+charoffset = 0;
+numberofcmps = 0;
+#ifdef SUPPORT_UNICODE
+typeoffset = 0;
+#endif
+
+while (*cc != XCL_END)
+ {
+ compares--;
+ invertcmp = (compares == 0 && list != backtracks);
+ jump = NULL;
+
+ if (*cc == XCL_SINGLE)
+ {
+ cc ++;
+ GETCHARINCTEST(c, cc);
+
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
+ OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
+ numberofcmps = 0;
+ }
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc ++;
+ GETCHARINCTEST(c, cc);
+ SET_CHAR_OFFSET(c);
+ GETCHARINCTEST(c, cc);
+
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
+ OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
+ numberofcmps = 0;
+ }
+ }
+#ifdef SUPPORT_UNICODE
+ else
+ {
+ SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
+ if (*cc == XCL_NOTPROP)
+ invertcmp ^= 0x1;
+ cc++;
+ switch(*cc)
+ {
+ case PT_ANY:
+ if (!invertcmp)
+ jump = JUMP(SLJIT_JUMP);
+ break;
+
+ case PT_LAMP:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_GC:
+ c = PRIV(ucp_typerange)[(int)cc[1] * 2];
+ SET_TYPE_OFFSET(c);
+ jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
+ break;
+
+ case PT_PC:
+ jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
+ break;
+
+ case PT_SC:
+ compares++;
+ /* Do nothing. */
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ SET_CHAR_OFFSET(9);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+ SET_TYPE_OFFSET(ucp_Zl);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_WORD:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ /* Fall through. */
+
+ case PT_ALNUM:
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
+ SET_TYPE_OFFSET(ucp_Nd);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_CLIST:
+ other_cases = PRIV(ucd_caseless_sets) + cc[1];
+
+ /* At least three characters are required.
+ Otherwise this case would be handled by the normal code path. */
+ SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
+ SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
+
+ /* Optimizing character pairs, if their difference is power of 2. */
+ if (is_powerof2(other_cases[1] ^ other_cases[0]))
+ {
+ if (charoffset == 0)
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
+ else
+ {
+ OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
+ }
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ other_cases += 2;
+ }
+ else if (is_powerof2(other_cases[2] ^ other_cases[1]))
+ {
+ if (charoffset == 0)
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
+ else
+ {
+ OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
+ }
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
+ OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+ other_cases += 3;
+ }
+ else
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ }
+
+ while (*other_cases != NOTACHAR)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
+ OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ }
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_UCNC:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+ SET_CHAR_OFFSET(0xa0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ SET_CHAR_OFFSET(0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL);
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_PXGRAPH:
+ /* C and Z groups are the farthest two groups. */
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
+
+ jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
+
+ /* In case of ucp_Cf, we overwrite the result. */
+ SET_CHAR_OFFSET(0x2066);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+ JUMPHERE(jump);
+ jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
+ break;
+
+ case PT_PXPRINT:
+ /* C and Z groups are the farthest two groups. */
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
+ OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
+
+ jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
+
+ /* In case of ucp_Cf, we overwrite the result. */
+ SET_CHAR_OFFSET(0x2066);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+
+ JUMPHERE(jump);
+ jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
+ break;
+
+ case PT_PXPUNCT:
+ SET_TYPE_OFFSET(ucp_Sc);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+
+ SET_CHAR_OFFSET(0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
+ OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+
+ SET_TYPE_OFFSET(ucp_Pc);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+ jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ cc += 2;
+ }
+#endif
+
+ if (jump != NULL)
+ add_jump(compiler, compares > 0 ? list : backtracks, jump);
+ }
+
+if (found != NULL)
+ set_jumps(found, LABEL());
+}
+
+#undef SET_TYPE_OFFSET
+#undef SET_CHAR_OFFSET
+
+#endif
+
+static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+int length;
+struct sljit_jump *jump[4];
+#ifdef SUPPORT_UNICODE
+struct sljit_label *label;
+#endif /* SUPPORT_UNICODE */
+
+switch(type)
+ {
+ case OP_SOD:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
+ return cc;
+
+ case OP_EODN:
+ /* Requires rather complex checks. */
+ jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ else
+ {
+ jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));
+ check_partial(common, TRUE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(jump[1]);
+ }
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else if (common->nltype == NLTYPE_FIXED)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+ else
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+ jump[2] = JUMP(SLJIT_GREATER);
+ add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
+ /* Equal. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+
+ JUMPHERE(jump[1]);
+ if (common->nltype == NLTYPE_ANYCRLF)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+ }
+ JUMPHERE(jump[2]);
+ JUMPHERE(jump[3]);
+ }
+ JUMPHERE(jump[0]);
+ check_partial(common, FALSE);
+ return cc;
+
+ case OP_EOD:
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
+ check_partial(common, FALSE);
+ return cc;
+
+ case OP_DOLL:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+
+ if (!common->endonly)
+ compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);
+ else
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
+ check_partial(common, FALSE);
+ }
+ return cc;
+
+ case OP_DOLLM:
+ jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+ check_partial(common, FALSE);
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));
+ else
+ {
+ jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
+ /* STR_PTR = STR_END - IN_UCHARS(1) */
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ check_partial(common, TRUE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(jump[1]);
+ }
+
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ peek_char(common, common->nlmax);
+ check_newlinechar(common, common->nltype, backtracks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_CIRC:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
+ OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+ return cc;
+
+ case OP_CIRCM:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0);
+ OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ if (!common->alt_circumflex)
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ skip_char_back(common);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
+ check_newlinechar(common, common->nltype, backtracks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_REVERSE:
+ length = GET(cc, 0);
+ if (length == 0)
+ return cc + LINK_SIZE;
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+#ifdef SUPPORT_UNICODE
+ if (common->utf)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
+ label = LABEL();
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
+ skip_char_back(common);
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ }
+ else
+#endif
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0));
+ }
+ check_start_used_ptr(common);
+ return cc + LINK_SIZE;
+ }
+SLJIT_ASSERT_STOP();
+return cc;
+}
+
+static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr)
+{
+DEFINE_COMPILER;
+int length;
+unsigned int c, oc, bit;
+compare_context context;
+struct sljit_jump *jump[3];
+jump_list *end_list;
+#ifdef SUPPORT_UNICODE
+struct sljit_label *label;
+PCRE2_UCHAR propdata[5];
+#endif /* SUPPORT_UNICODE */
+
+switch(type)
+ {
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ /* Digits are usually 0-9, so it is worth to optimize them. */
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE))
+ read_char7_type(common, type == OP_NOT_DIGIT);
+ else
+#endif
+ read_char8_type(common, type == OP_NOT_DIGIT);
+ /* Flip the starting bit in the negative case. */
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
+ add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE))
+ read_char7_type(common, type == OP_NOT_WHITESPACE);
+ else
+#endif
+ read_char8_type(common, type == OP_NOT_WHITESPACE);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
+ add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE))
+ read_char7_type(common, type == OP_NOT_WORDCHAR);
+ else
+#endif
+ read_char8_type(common, type == OP_NOT_WORDCHAR);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
+ add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
+ return cc;
+
+ case OP_ANY:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
+ end_list = NULL;
+ if (common->mode != PCRE2_JIT_PARTIAL_HARD)
+ add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ else
+ check_str_end(common, &end_list);
+
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
+ set_jumps(end_list, LABEL());
+ JUMPHERE(jump[0]);
+ }
+ else
+ check_newlinechar(common, common->nltype, backtracks, TRUE);
+ return cc;
+
+ case OP_ALLANY:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#endif
+ JUMPHERE(jump[0]);
+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
+ return cc;
+ }
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+ case OP_ANYBYTE:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+#ifdef SUPPORT_UNICODE
+ case OP_NOTPROP:
+ case OP_PROP:
+ propdata[0] = XCL_HASPROP;
+ propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
+ propdata[2] = cc[0];
+ propdata[3] = cc[1];
+ propdata[4] = XCL_END;
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ compile_xclass_matchingpath(common, propdata, backtracks);
+ return cc + 2;
+#endif
+
+ case OP_ANYNL:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
+ jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ /* We don't need to handle soft partial matching case. */
+ end_list = NULL;
+ if (common->mode != PCRE2_JIT_PARTIAL_HARD)
+ add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ else
+ check_str_end(common, &end_list);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[2] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[0]);
+ check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
+ set_jumps(end_list, LABEL());
+ JUMPHERE(jump[1]);
+ JUMPHERE(jump[2]);
+ return cc;
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
+ add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
+ return cc;
+
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
+ add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
+ return cc;
+
+#ifdef SUPPORT_UNICODE
+ case OP_EXTUNI:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
+ /* Optimize register allocation: use a real register. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
+ OP1(SLJIT_MOV_U8, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+
+ label = LABEL();
+ jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
+ OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+
+ OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
+ OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
+ OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ JUMPHERE(jump[0]);
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+
+ if (common->mode == PCRE2_JIT_PARTIAL_HARD)
+ {
+ jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
+ /* Since we successfully read a char above, partial matching must occure. */
+ check_partial(common, TRUE);
+ JUMPHERE(jump[0]);
+ }
+ return cc;
+#endif
+
+ case OP_CHAR:
+ case OP_CHARI:
+ length = 1;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
+#endif
+ if (common->mode == PCRE2_JIT_COMPLETE && check_str_ptr
+ && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
+ {
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.length = IN_UCHARS(length);
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
+ }
+
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+#ifdef SUPPORT_UNICODE
+ if (common->utf)
+ {
+ GETCHAR(c, cc);
+ }
+ else
+#endif
+ c = *cc;
+
+ if (type == OP_CHAR || !char_has_othercase(common, cc))
+ {
+ read_char_range(common, c, c, FALSE);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ return cc + length;
+ }
+ oc = char_othercase(common, c);
+ read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE);
+ bit = c ^ oc;
+ if (is_powerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
+ return cc + length;
+ }
+ jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
+ JUMPHERE(jump[0]);
+ return cc + length;
+
+ case OP_NOT:
+ case OP_NOTI:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+
+ length = 1;
+#ifdef SUPPORT_UNICODE
+ if (common->utf)
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ c = *cc;
+ if (c < 128)
+ {
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ else
+ {
+ /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
+ }
+ /* Skip the variable-length character. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(jump[0]);
+ return cc + 1;
+ }
+ else
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ {
+ GETCHARLEN(c, cc, length);
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+ c = *cc;
+
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ {
+ read_char_range(common, c, c, TRUE);
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ }
+ else
+ {
+ oc = char_othercase(common, c);
+ read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE);
+ bit = c ^ oc;
+ if (is_powerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
+ }
+ else
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
+ }
+ }
+ return cc + length;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255;
+ read_char_range(common, 0, bit, type == OP_NCLASS);
+#else
+ read_char_range(common, 0, 255, type == OP_NCLASS);
+#endif
+
+ if (check_class_ranges(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks))
+ return cc + 32 / sizeof(PCRE2_UCHAR);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ jump[0] = NULL;
+ if (common->utf)
+ {
+ jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);
+ if (type == OP_CLASS)
+ {
+ add_jump(compiler, backtracks, jump[0]);
+ jump[0] = NULL;
+ }
+ }
+#elif PCRE2_CODE_UNIT_WIDTH != 8
+ jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ if (type == OP_CLASS)
+ {
+ add_jump(compiler, backtracks, jump[0]);
+ jump[0] = NULL;
+ }
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
+
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ if (jump[0] != NULL)
+ JUMPHERE(jump[0]);
+#endif
+ return cc + 32 / sizeof(PCRE2_UCHAR);
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ case OP_XCLASS:
+ if (check_str_ptr)
+ detect_partial_match(common, backtracks);
+ compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
+ return cc + GET(cc, 0) - 1;
+#endif
+ }
+SLJIT_ASSERT_STOP();
+return cc;
+}
+
+static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks)
+{
+/* This function consumes at least one input character. */
+/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
+DEFINE_COMPILER;
+PCRE2_SPTR ccbegin = cc;
+compare_context context;
+int size;
+
+context.length = 0;
+do
+ {
+ if (cc >= ccend)
+ break;
+
+ if (*cc == OP_CHAR)
+ {
+ size = 1;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+#endif
+ }
+ else if (*cc == OP_CHARI)
+ {
+ size = 1;
+#ifdef SUPPORT_UNICODE
+ if (common->utf)
+ {
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ else if (HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+ }
+ else
+#endif
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ }
+ else
+ size = 0;
+
+ cc += 1 + size;
+ context.length += IN_UCHARS(size);
+ }
+while (size > 0 && context.length <= 128);
+
+cc = ccbegin;
+if (context.length > 0)
+ {
+ /* We have a fixed-length byte sequence. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
+ return cc;
+ }
+
+/* A non-fixed length character will be checked if length == 0. */
+return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE);
+}
+
+/* Forward definitions. */
+static void compile_matchingpath(compiler_common *, PCRE2_SPTR, PCRE2_SPTR, backtrack_common *);
+static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
+
+#define PUSH_BACKTRACK(size, ccstart, error) \
+ do \
+ { \
+ backtrack = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return error; \
+ memset(backtrack, 0, size); \
+ backtrack->prev = parent->top; \
+ backtrack->cc = (ccstart); \
+ parent->top = backtrack; \
+ } \
+ while (0)
+
+#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
+ do \
+ { \
+ backtrack = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ memset(backtrack, 0, size); \
+ backtrack->prev = parent->top; \
+ backtrack->cc = (ccstart); \
+ parent->top = backtrack; \
+ } \
+ while (0)
+
+#define BACKTRACK_AS(type) ((type *)backtrack)
+
+static void compile_dnref_search(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)
+{
+/* The OVECTOR offset goes to TMP2. */
+DEFINE_COMPILER;
+int count = GET2(cc, 1 + IMM2_SIZE);
+PCRE2_SPTR slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
+unsigned int offset;
+jump_list *found = NULL;
+
+SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
+
+count--;
+while (count-- > 0)
+ {
+ offset = GET2(slot, 0) << 1;
+ GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
+ add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
+ slot += common->name_entry_size;
+ }
+
+offset = GET2(slot, 0) << 1;
+GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
+if (backtracks != NULL && !common->unset_backref)
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
+
+set_jumps(found, LABEL());
+}
+
+static void compile_ref_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
+{
+DEFINE_COMPILER;
+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
+int offset = 0;
+struct sljit_jump *jump = NULL;
+struct sljit_jump *partial;
+struct sljit_jump *nopartial;
+
+if (ref)
+ {
+ offset = GET2(cc, 1) << 1;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ /* OVECTOR(1) contains the "string begin - 1" constant. */
+ if (withchecks && !common->unset_backref)
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
+ }
+else
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+
+#if defined SUPPORT_UNICODE
+if (common->utf && *cc == OP_REFI)
+ {
+ SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
+ if (ref)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ else
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+
+ if (withchecks)
+ jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
+
+ /* Needed to save important temporary registers. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), STR_PTR, 0);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
+ else
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
+ nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+ check_partial(common, FALSE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(nopartial);
+ }
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+ }
+else
+#endif /* SUPPORT_UNICODE */
+ {
+ if (ref)
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
+ else
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
+
+ if (withchecks)
+ jump = JUMP(SLJIT_ZERO);
+
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, backtracks, partial);
+
+ add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ {
+ nopartial = JUMP(SLJIT_JUMP);
+ JUMPHERE(partial);
+ /* TMP2 -= STR_END - STR_PTR */
+ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
+ partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
+ add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ JUMPHERE(partial);
+ check_partial(common, FALSE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(nopartial);
+ }
+ }
+
+if (jump != NULL)
+ {
+ if (emptyfail)
+ add_jump(compiler, backtracks, jump);
+ else
+ JUMPHERE(jump);
+ }
+}
+
+static SLJIT_INLINE PCRE2_SPTR compile_ref_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
+backtrack_common *backtrack;
+PCRE2_UCHAR type;
+int offset = 0;
+struct sljit_label *label;
+struct sljit_jump *zerolength;
+struct sljit_jump *jump = NULL;
+PCRE2_SPTR ccbegin = cc;
+int min = 0, max = 0;
+BOOL minimize;
+
+PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL);
+
+if (ref)
+ offset = GET2(cc, 1) << 1;
+else
+ cc += IMM2_SIZE;
+type = cc[1 + IMM2_SIZE];
+
+SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
+minimize = (type & 0x1) != 0;
+switch(type)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ min = 0;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ min = 1;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ min = 0;
+ max = 1;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(cc, 1 + IMM2_SIZE + 1);
+ max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
+ cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+if (!minimize)
+ {
+ if (min == 0)
+ {
+ allocate_stack(common, 2);
+ if (ref)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+ /* Temporary release of STR_PTR. */
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+ /* Handles both invalid and empty cases. Since the minimum repeat,
+ is zero the invalid case is basically the same as an empty case. */
+ if (ref)
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ else
+ {
+ compile_dnref_search(common, ccbegin, NULL);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
+ /* Restore if not zero length. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+ }
+ else
+ {
+ allocate_stack(common, 1);
+ if (ref)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ if (ref)
+ {
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ }
+ else
+ {
+ compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
+ }
+
+ if (min > 1 || max > 1)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);
+
+ label = LABEL();
+ if (!ref)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
+ compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
+
+ if (min > 1 || max > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
+ if (min > 1)
+ CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);
+ if (max > 1)
+ {
+ jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ JUMPHERE(jump);
+ }
+ }
+
+ if (max == 0)
+ {
+ /* Includes min > 1 case as well. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+
+ JUMPHERE(zerolength);
+ BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
+
+ count_match(common);
+ return cc;
+ }
+
+allocate_stack(common, ref ? 2 : 3);
+if (ref)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+if (type != OP_CRMINSTAR)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+
+if (min == 0)
+ {
+ /* Handles both invalid and empty cases. Since the minimum repeat,
+ is zero the invalid case is basically the same as an empty case. */
+ if (ref)
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ else
+ {
+ compile_dnref_search(common, ccbegin, NULL);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
+ /* Length is non-zero, we can match real repeats. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ jump = JUMP(SLJIT_JUMP);
+ }
+else
+ {
+ if (ref)
+ {
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ }
+ else
+ {
+ compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
+ zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
+ }
+
+BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
+if (max > 0)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
+
+if (!ref)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
+compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+if (min > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath);
+ }
+else if (max > 0)
+ OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+
+if (jump != NULL)
+ JUMPHERE(jump);
+JUMPHERE(zerolength);
+
+count_match(common);
+return cc;
+}
+
+static SLJIT_INLINE PCRE2_SPTR compile_recurse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+recurse_entry *entry = common->entries;
+recurse_entry *prev = NULL;
+sljit_sw start = GET(cc, 1);
+PCRE2_SPTR start_cc;
+BOOL needs_control_head;
+
+PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
+
+/* Inlining simple patterns. */
+if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
+ {
+ start_cc = common->start + start;
+ compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
+ BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
+ return cc + 1 + LINK_SIZE;
+ }
+
+while (entry != NULL)
+ {
+ if (entry->start == start)
+ break;
+ prev = entry;
+ entry = entry->next;
+ }
+
+if (entry == NULL)
+ {
+ entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ entry->next = NULL;
+ entry->entry = NULL;
+ entry->calls = NULL;
+ entry->start = start;
+
+ if (prev != NULL)
+ prev->next = entry;
+ else
+ common->entries = entry;
+ }
+
+if (common->has_set_som && common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ }
+else if (common->has_set_som || common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+
+if (entry->entry == NULL)
+ add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
+else
+ JUMPTO(SLJIT_FAST_CALL, entry->entry);
+/* Leave if the match is failed. */
+add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
+return cc + 1 + LINK_SIZE;
+}
+
+static int SLJIT_CALL do_callout(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
+{
+PCRE2_SPTR begin = arguments->begin;
+PCRE2_SIZE *ovector = arguments->match_data->ovector;
+sljit_u32 oveccount = arguments->oveccount;
+sljit_u32 i;
+
+if (arguments->callout == NULL)
+ return 0;
+
+callout_block->version = 1;
+
+/* Offsets in subject. */
+callout_block->subject_length = arguments->end - arguments->begin;
+callout_block->start_match = (PCRE2_SPTR)callout_block->subject - arguments->begin;
+callout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - arguments->begin;
+callout_block->subject = begin;
+
+/* Convert and copy the JIT offset vector to the ovector array. */
+callout_block->capture_top = 0;
+callout_block->offset_vector = ovector;
+for (i = 2; i < oveccount; i += 2)
+ {
+ ovector[i] = jit_ovector[i] - begin;
+ ovector[i + 1] = jit_ovector[i + 1] - begin;
+ if (jit_ovector[i] >= begin)
+ callout_block->capture_top = i;
+ }
+
+callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
+ovector[0] = PCRE2_UNSET;
+ovector[1] = PCRE2_UNSET;
+return (arguments->callout)(callout_block, arguments->callout_data);
+}
+
+/* Aligning to 8 byte. */
+#define CALLOUT_ARG_SIZE \
+ (((int)sizeof(pcre2_callout_block) + 7) & ~7)
+
+#define CALLOUT_ARG_OFFSET(arg) \
+ (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(pcre2_callout_block, arg))
+
+static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+sljit_s32 mov_opcode;
+unsigned int callout_length = (*cc == OP_CALLOUT)
+ ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE);
+sljit_sw value1;
+sljit_sw value2;
+sljit_sw value3;
+
+PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
+
+allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
+
+SLJIT_ASSERT(common->capture_last_ptr != 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+value1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0;
+OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1);
+OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
+
+/* These pointer sized fields temporarly stores internal variables. */
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
+
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
+mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
+OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1));
+OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE));
+
+if (*cc == OP_CALLOUT)
+ {
+ value1 = 0;
+ value2 = 0;
+ value3 = 0;
+ }
+else
+ {
+ value1 = (sljit_sw) (cc + (1 + 4*LINK_SIZE) + 1);
+ value2 = (callout_length - (1 + 4*LINK_SIZE + 2));
+ value3 = (sljit_sw) (GET(cc, 1 + 3*LINK_SIZE));
+ }
+
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string), SLJIT_IMM, value1);
+OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length), SLJIT_IMM, value2);
+OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
+
+/* Needed to save important temporary registers. */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
+OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
+GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
+sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
+OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
+
+/* Check return value. */
+OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
+if (common->forced_quit_label == NULL)
+ add_jump(compiler, &common->forced_quit, JUMP(SLJIT_SIG_LESS));
+else
+ JUMPTO(SLJIT_SIG_LESS, common->forced_quit_label);
+return cc + callout_length;
+}
+
+#undef CALLOUT_ARG_SIZE
+#undef CALLOUT_ARG_OFFSET
+
+static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc)
+{
+while (TRUE)
+ {
+ switch (*cc)
+ {
+ case OP_CALLOUT_STR:
+ cc += GET(cc, 1 + 2*LINK_SIZE);
+ break;
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_CALLOUT:
+ case OP_ALT:
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ case OP_KET:
+ return FALSE;
+
+ default:
+ return TRUE;
+ }
+ }
+}
+
+static PCRE2_SPTR compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backtrack *backtrack, BOOL conditional)
+{
+DEFINE_COMPILER;
+int framesize;
+int extrasize;
+BOOL needs_control_head;
+int private_data_ptr;
+backtrack_common altbacktrack;
+PCRE2_SPTR ccbegin;
+PCRE2_UCHAR opcode;
+PCRE2_UCHAR bra = OP_BRA;
+jump_list *tmp = NULL;
+jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
+jump_list **found;
+/* Saving previous accept variables. */
+BOOL save_local_exit = common->local_exit;
+BOOL save_positive_assert = common->positive_assert;
+then_trap_backtrack *save_then_trap = common->then_trap;
+struct sljit_label *save_quit_label = common->quit_label;
+struct sljit_label *save_accept_label = common->accept_label;
+jump_list *save_quit = common->quit;
+jump_list *save_positive_assert_quit = common->positive_assert_quit;
+jump_list *save_accept = common->accept;
+struct sljit_jump *jump;
+struct sljit_jump *brajump = NULL;
+
+/* Assert captures then. */
+common->then_trap = NULL;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ SLJIT_ASSERT(!conditional);
+ bra = *cc;
+ cc++;
+ }
+private_data_ptr = PRIVATE_DATA(cc);
+SLJIT_ASSERT(private_data_ptr != 0);
+framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
+backtrack->framesize = framesize;
+backtrack->private_data_ptr = private_data_ptr;
+opcode = *cc;
+SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
+found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
+ccbegin = cc;
+cc += GET(cc, 1);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a braminzero backtrack path. */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (framesize < 0)
+ {
+ extrasize = 1;
+ if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE))
+ extrasize = 0;
+
+ if (needs_control_head)
+ extrasize++;
+
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
+
+ if (extrasize > 0)
+ allocate_stack(common, extrasize);
+
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+
+ if (extrasize > 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+ if (needs_control_head)
+ {
+ SLJIT_ASSERT(extrasize == 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ }
+ }
+else
+ {
+ extrasize = needs_control_head ? 3 : 2;
+ allocate_stack(common, framesize + extrasize);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+ if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+
+ init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
+ }
+
+memset(&altbacktrack, 0, sizeof(backtrack_common));
+if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ /* Negative assert is stronger than positive assert. */
+ common->local_exit = TRUE;
+ common->quit_label = NULL;
+ common->quit = NULL;
+ common->positive_assert = FALSE;
+ }
+else
+ common->positive_assert = TRUE;
+common->positive_assert_quit = NULL;
+
+while (1)
+ {
+ common->accept_label = NULL;
+ common->accept = NULL;
+ altbacktrack.top = NULL;
+ altbacktrack.topbacktracks = NULL;
+
+ if (*ccbegin == OP_ALT && extrasize > 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ altbacktrack.cc = ccbegin;
+ compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ common->local_exit = save_local_exit;
+ common->quit_label = save_quit_label;
+ common->quit = save_quit;
+ }
+ common->positive_assert = save_positive_assert;
+ common->then_trap = save_then_trap;
+ common->accept_label = save_accept_label;
+ common->positive_assert_quit = save_positive_assert_quit;
+ common->accept = save_accept;
+ return NULL;
+ }
+ common->accept_label = LABEL();
+ if (common->accept != NULL)
+ set_jumps(common->accept, common->accept_label);
+
+ /* Reset stack. */
+ if (framesize < 0)
+ {
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ else if (extrasize > 0)
+ free_stack(common, extrasize);
+
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ else
+ {
+ if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
+ {
+ /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ }
+
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ if (conditional)
+ {
+ if (extrasize > 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
+ }
+ else if (bra == OP_BRAZERO)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
+ }
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else if (framesize >= 0)
+ {
+ /* For OP_BRA and OP_BRAMINZERO. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
+ }
+ }
+ add_jump(compiler, found, JUMP(SLJIT_JUMP));
+
+ compile_backtrackingpath(common, altbacktrack.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ common->local_exit = save_local_exit;
+ common->quit_label = save_quit_label;
+ common->quit = save_quit;
+ }
+ common->positive_assert = save_positive_assert;
+ common->then_trap = save_then_trap;
+ common->accept_label = save_accept_label;
+ common->positive_assert_quit = save_positive_assert_quit;
+ common->accept = save_accept;
+ return NULL;
+ }
+ set_jumps(altbacktrack.topbacktracks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ ccbegin = cc;
+ cc += GET(cc, 1);
+ }
+
+if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ SLJIT_ASSERT(common->positive_assert_quit == NULL);
+ /* Makes the check less complicated below. */
+ common->positive_assert_quit = common->quit;
+ }
+
+/* None of them matched. */
+if (common->positive_assert_quit != NULL)
+ {
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(common->positive_assert_quit, LABEL());
+ SLJIT_ASSERT(framesize != no_stack);
+ if (framesize < 0)
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
+ else
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
+ }
+ JUMPHERE(jump);
+ }
+
+if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
+
+if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
+ {
+ /* Assert is failed. */
+ if ((conditional && extrasize > 0) || bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ if (framesize < 0)
+ {
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ {
+ if (extrasize == 2)
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else if (extrasize > 0)
+ free_stack(common, extrasize);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ {
+ free_stack(common, framesize + extrasize - 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + extrasize);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
+ }
+ jump = JUMP(SLJIT_JUMP);
+ if (bra != OP_BRAZERO)
+ add_jump(compiler, target, jump);
+
+ /* Assert is successful. */
+ set_jumps(tmp, LABEL());
+ if (framesize < 0)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ if (extrasize > 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
+
+ /* Keep the STR_PTR on the top of the stack. */
+ if (bra == OP_BRAZERO)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+ if (extrasize == 2)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else if (bra == OP_BRAMINZERO)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+ else
+ {
+ if (bra == OP_BRA)
+ {
+ /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
+ }
+ else
+ {
+ /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
+ if (extrasize == 2)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (bra == OP_BRAMINZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
+ }
+ }
+ }
+
+ if (bra == OP_BRAZERO)
+ {
+ backtrack->matchingpath = LABEL();
+ SET_LABEL(jump, backtrack->matchingpath);
+ }
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
+ JUMPHERE(brajump);
+ if (framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
+ }
+ set_jumps(backtrack->common.topbacktracks, LABEL());
+ }
+ }
+else
+ {
+ /* AssertNot is successful. */
+ if (framesize < 0)
+ {
+ if (extrasize > 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ if (bra != OP_BRA)
+ {
+ if (extrasize == 2)
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else if (extrasize > 0)
+ free_stack(common, extrasize);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
+ /* The topmost item should be 0. */
+ if (bra != OP_BRA)
+ {
+ free_stack(common, framesize + extrasize - 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + extrasize);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
+ }
+
+ if (bra == OP_BRAZERO)
+ backtrack->matchingpath = LABEL();
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
+ JUMPHERE(brajump);
+ }
+
+ if (bra != OP_BRA)
+ {
+ SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
+ set_jumps(backtrack->common.topbacktracks, LABEL());
+ backtrack->common.topbacktracks = NULL;
+ }
+ }
+
+if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ common->local_exit = save_local_exit;
+ common->quit_label = save_quit_label;
+ common->quit = save_quit;
+ }
+common->positive_assert = save_positive_assert;
+common->then_trap = save_then_trap;
+common->accept_label = save_accept_label;
+common->positive_assert_quit = save_positive_assert_quit;
+common->accept = save_accept;
+return cc + 1 + LINK_SIZE;
+}
+
+static SLJIT_INLINE void match_once_common(compiler_common *common, PCRE2_UCHAR ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
+{
+DEFINE_COMPILER;
+int stacksize;
+
+if (framesize < 0)
+ {
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ else
+ {
+ stacksize = needs_control_head ? 1 : 0;
+ if (ket != OP_KET || has_alternatives)
+ stacksize++;
+
+ if (stacksize > 0)
+ free_stack(common, stacksize);
+ }
+
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
+
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ if (ket == OP_KETRMAX)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (ket == OP_KETRMIN)
+ {
+ /* Move the STR_PTR to the private_data_ptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ }
+else
+ {
+ stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
+
+ if (ket == OP_KETRMAX)
+ {
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ }
+if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
+}
+
+static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
+{
+DEFINE_COMPILER;
+
+if (common->capture_last_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
+ stacksize++;
+ }
+if (common->optimized_cbracket[offset >> 1] == 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
+ stacksize += 2;
+ }
+return stacksize;
+}
+
+/*
+ Handling bracketed expressions is probably the most complex part.
+
+ Stack layout naming characters:
+ S - Push the current STR_PTR
+ 0 - Push a 0 (NULL)
+ A - Push the current STR_PTR. Needed for restoring the STR_PTR
+ before the next alternative. Not pushed if there are no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+ C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
+ L - Push the previous local (pointed by localptr) to the stack
+ () - opional values stored on the stack
+ ()* - optonal, can be stored multiple times
+
+ The following list shows the regular expression templates, their PCRE byte codes
+ and stack layout supported by pcre-sljit.
+
+ (?:) OP_BRA | OP_KET A M
+ () OP_CBRA | OP_KET C M
+ (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMAX 0 L M S ( L M S )*
+ (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMIN 0 L M S ( L M S )*
+ ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )*
+ ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )*
+ (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 )
+ (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 )
+ ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 )
+ ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 )
+ (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )*
+ OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )*
+ (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )*
+ OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )*
+ ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )*
+ OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )*
+ ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )*
+ OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )*
+
+
+ Stack layout naming characters:
+ A - Push the alternative index (starting from 0) on the stack.
+ Not pushed if there is no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+
+ The next list shows the possible content of a bracket:
+ (|) OP_*BRA | OP_ALT ... M A
+ (?()|) OP_*COND | OP_ALT M A
+ (?>|) OP_ONCE | OP_ALT ... [stack trace] M A
+ (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A
+ Or nothing, if trace is unnecessary
+*/
+
+static PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+PCRE2_UCHAR opcode;
+int private_data_ptr = 0;
+int offset = 0;
+int i, stacksize;
+int repeat_ptr = 0, repeat_length = 0;
+int repeat_type = 0, repeat_count = 0;
+PCRE2_SPTR ccbegin;
+PCRE2_SPTR matchingpath;
+PCRE2_SPTR slot;
+PCRE2_UCHAR bra = OP_BRA;
+PCRE2_UCHAR ket;
+assert_backtrack *assert;
+BOOL has_alternatives;
+BOOL needs_control_head = FALSE;
+struct sljit_jump *jump;
+struct sljit_jump *skip;
+struct sljit_label *rmax_label = NULL;
+struct sljit_jump *braminzero = NULL;
+
+PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ opcode = *cc;
+ }
+
+opcode = *cc;
+ccbegin = cc;
+matchingpath = bracketend(cc) - 1 - LINK_SIZE;
+ket = *matchingpath;
+if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
+ {
+ repeat_ptr = PRIVATE_DATA(matchingpath);
+ repeat_length = PRIVATE_DATA(matchingpath + 1);
+ repeat_type = PRIVATE_DATA(matchingpath + 2);
+ repeat_count = PRIVATE_DATA(matchingpath + 3);
+ SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
+ if (repeat_type == OP_UPTO)
+ ket = OP_KETRMAX;
+ if (repeat_type == OP_MINUPTO)
+ ket = OP_KETRMIN;
+ }
+
+matchingpath = ccbegin + 1 + LINK_SIZE;
+SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
+SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
+cc += GET(cc, 1);
+
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
+ {
+ SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3,
+ compile_time_checks_must_be_grouped_together);
+ has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE;
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Capturing brackets has a pre-allocated space. */
+ offset = GET2(ccbegin, 1 + LINK_SIZE);
+ if (common->optimized_cbracket[offset] == 0)
+ {
+ private_data_ptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ }
+ else
+ {
+ offset <<= 1;
+ private_data_ptr = OVECTOR(offset);
+ }
+ BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
+ matchingpath += IMM2_SIZE;
+ }
+else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Other brackets simply allocate the next entry. */
+ private_data_ptr = PRIVATE_DATA(ccbegin);
+ SLJIT_ASSERT(private_data_ptr != 0);
+ BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
+ if (opcode == OP_ONCE)
+ BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
+ }
+
+/* Instructions before the first alternative. */
+stacksize = 0;
+if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ stacksize++;
+if (bra == OP_BRAZERO)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (ket != OP_KETRMIN)
+ {
+ free_stack(common, 1);
+ braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* Nothing stored during the first run. */
+ skip = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump);
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
+ {
+ /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
+ braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ }
+ else
+ {
+ /* Except when the whole stack frame must be saved. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
+ }
+ JUMPHERE(skip);
+ }
+ else
+ {
+ jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPHERE(jump);
+ }
+ }
+ }
+
+if (repeat_type != 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count);
+ if (repeat_type == OP_EXACT)
+ rmax_label = LABEL();
+ }
+
+if (ket == OP_KETRMIN)
+ BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
+
+if (ket == OP_KETRMAX)
+ {
+ rmax_label = LABEL();
+ if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
+ BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
+ }
+
+/* Handling capturing brackets and alternatives. */
+if (opcode == OP_ONCE)
+ {
+ stacksize = 0;
+ if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ stacksize++;
+ }
+
+ if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
+ {
+ /* Neither capturing brackets nor recursions are found in the block. */
+ if (ket == OP_KETRMIN)
+ {
+ stacksize += 2;
+ if (!needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ }
+ else
+ {
+ if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
+ if (ket == OP_KETRMAX || has_alternatives)
+ stacksize++;
+ }
+
+ if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+ stacksize = 0;
+ if (needs_control_head)
+ {
+ stacksize++;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+
+ if (ket == OP_KETRMIN)
+ {
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
+ }
+ else if (ket == OP_KETRMAX || has_alternatives)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ }
+ else
+ {
+ if (ket != OP_KET || has_alternatives)
+ stacksize++;
+
+ stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
+ allocate_stack(common, stacksize);
+
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
+
+ stacksize = needs_control_head ? 1 : 0;
+ if (ket != OP_KET || has_alternatives)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
+ stacksize++;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
+ }
+ init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
+ }
+ }
+else if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Saving the previous values. */
+ if (common->optimized_cbracket[offset >> 1] != 0)
+ {
+ SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Saving the previous value. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+else if (has_alternatives)
+ {
+ /* Pushing the starting string pointer. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+/* Generating code for the first alternative. */
+if (opcode == OP_COND || opcode == OP_SCOND)
+ {
+ if (*matchingpath == OP_CREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
+ CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
+ matchingpath += 1 + IMM2_SIZE;
+ }
+ else if (*matchingpath == OP_DNCREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+
+ i = GET2(matchingpath, 1 + IMM2_SIZE);
+ slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
+ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
+ slot += common->name_entry_size;
+ i--;
+ while (i-- > 0)
+ {
+ OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
+ OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
+ slot += common->name_entry_size;
+ }
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO));
+ matchingpath += 1 + 2 * IMM2_SIZE;
+ }
+ else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL)
+ {
+ /* Never has other case. */
+ BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
+ SLJIT_ASSERT(!has_alternatives);
+
+ if (*matchingpath == OP_TRUE)
+ {
+ stacksize = 1;
+ matchingpath++;
+ }
+ else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL)
+ stacksize = 0;
+ else if (*matchingpath == OP_RREF)
+ {
+ stacksize = GET2(matchingpath, 1);
+ if (common->currententry == NULL)
+ stacksize = 0;
+ else if (stacksize == RREF_ANY)
+ stacksize = 1;
+ else if (common->currententry->start == 0)
+ stacksize = stacksize == 0;
+ else
+ stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+
+ if (stacksize != 0)
+ matchingpath += 1 + IMM2_SIZE;
+ }
+ else
+ {
+ if (common->currententry == NULL || common->currententry->start == 0)
+ stacksize = 0;
+ else
+ {
+ stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
+ slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
+ i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+ while (stacksize > 0)
+ {
+ if ((int)GET2(slot, 0) == i)
+ break;
+ slot += common->name_entry_size;
+ stacksize--;
+ }
+ }
+
+ if (stacksize != 0)
+ matchingpath += 1 + 2 * IMM2_SIZE;
+ }
+
+ /* The stacksize == 0 is a common "else" case. */
+ if (stacksize == 0)
+ {
+ if (*cc == OP_ALT)
+ {
+ matchingpath = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+ else
+ matchingpath = cc;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
+ /* Similar code as PUSH_BACKTRACK macro. */
+ assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ memset(assert, 0, sizeof(assert_backtrack));
+ assert->common.cc = matchingpath;
+ BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
+ matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
+ }
+ }
+
+compile_matchingpath(common, matchingpath, cc, backtrack);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+if (opcode == OP_ONCE)
+ match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
+
+stacksize = 0;
+if (repeat_type == OP_MINUPTO)
+ {
+ /* We need to preserve the counter. TMP2 will be used below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
+ stacksize++;
+ }
+if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+if (offset != 0)
+ {
+ if (common->capture_last_ptr != 0)
+ stacksize++;
+ if (common->optimized_cbracket[offset >> 1] == 0)
+ stacksize += 2;
+ }
+if (has_alternatives && opcode != OP_ONCE)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if (repeat_type == OP_MINUPTO)
+ {
+ /* TMP2 was set above. */
+ OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
+ stacksize++;
+ }
+
+if (ket != OP_KET || bra != OP_BRA)
+ {
+ if (ket != OP_KET)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (offset != 0)
+ stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
+
+if (has_alternatives)
+ {
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ if (ket != OP_KETRMAX)
+ BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
+ }
+
+/* Must be after the matchingpath label. */
+if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
+ {
+ SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ if (repeat_type != 0)
+ {
+ if (has_alternatives)
+ BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, rmax_label);
+ /* Drop STR_PTR for greedy plus quantifier. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ if (has_alternatives)
+ BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE)
+ {
+ CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label);
+ /* Drop STR_PTR for greedy plus quantifier. */
+ if (bra != OP_BRAZERO)
+ free_stack(common, 1);
+ }
+ else
+ /* TMP2 must contain the starting STR_PTR. */
+ CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, rmax_label);
+ BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
+ }
+
+if (repeat_type == OP_EXACT)
+ {
+ count_match(common);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, rmax_label);
+ }
+else if (repeat_type == OP_UPTO)
+ {
+ /* We need to preserve the counter. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+
+if (bra == OP_BRAZERO)
+ BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
+ JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
+ if (braminzero != NULL)
+ {
+ JUMPHERE(braminzero);
+ /* We need to release the end pointer to perform the
+ backtrack for the zero-length iteration. When
+ framesize is < 0, OP_ONCE will do the release itself. */
+ if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ else if (ket == OP_KETRMIN && opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ /* Continue to the normal backtrack. */
+ }
+
+if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
+ count_match(common);
+
+/* Skip the other alternatives. */
+while (*cc == OP_ALT)
+ cc += GET(cc, 1);
+cc += 1 + LINK_SIZE;
+
+if (opcode == OP_ONCE)
+ {
+ /* We temporarily encode the needs_control_head in the lowest bit.
+ Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns
+ the same value for small signed numbers (including negative numbers). */
+ BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
+ }
+return cc + repeat_length;
+}
+
+static PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+PCRE2_UCHAR opcode;
+int private_data_ptr;
+int cbraprivptr = 0;
+BOOL needs_control_head;
+int framesize;
+int stacksize;
+int offset = 0;
+BOOL zero = FALSE;
+PCRE2_SPTR ccbegin = NULL;
+int stack; /* Also contains the offset of control head. */
+struct sljit_label *loop = NULL;
+struct jump_list *emptymatch = NULL;
+
+PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
+if (*cc == OP_BRAPOSZERO)
+ {
+ zero = TRUE;
+ cc++;
+ }
+
+opcode = *cc;
+private_data_ptr = PRIVATE_DATA(cc);
+SLJIT_ASSERT(private_data_ptr != 0);
+BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
+switch(opcode)
+ {
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ ccbegin = cc + 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ offset = GET2(cc, 1 + LINK_SIZE);
+ /* This case cannot be optimized in the same was as
+ normal capturing brackets. */
+ SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
+ cbraprivptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
+BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
+if (framesize < 0)
+ {
+ if (offset != 0)
+ {
+ stacksize = 2;
+ if (common->capture_last_ptr != 0)
+ stacksize++;
+ }
+ else
+ stacksize = 1;
+
+ if (needs_control_head)
+ stacksize++;
+ if (!zero)
+ stacksize++;
+
+ BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
+ allocate_stack(common, stacksize);
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
+
+ stack = 0;
+ if (offset != 0)
+ {
+ stack = 2;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ if (common->capture_last_ptr != 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
+ stack = 3;
+ }
+ }
+ else
+ {
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ stack = 1;
+ }
+
+ if (needs_control_head)
+ stack++;
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
+ if (needs_control_head)
+ {
+ stack--;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
+ }
+ }
+else
+ {
+ stacksize = framesize + 1;
+ if (!zero)
+ stacksize++;
+ if (needs_control_head)
+ stacksize++;
+ if (offset == 0)
+ stacksize++;
+ BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
+
+ allocate_stack(common, stacksize);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
+
+ stack = 0;
+ if (!zero)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
+ stack = 1;
+ }
+ if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
+ stack++;
+ }
+ if (offset == 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
+ stack++;
+ }
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
+ init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
+ stack -= 1 + (offset == 0);
+ }
+
+if (offset != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
+
+loop = LABEL();
+while (*cc != OP_KETRPOS)
+ {
+ backtrack->top = NULL;
+ backtrack->topbacktracks = NULL;
+ cc += GET(cc, 1);
+
+ compile_matchingpath(common, ccbegin, cc, backtrack);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+ if (framesize < 0)
+ {
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+
+ if (offset != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+ /* Even if the match is empty, we need to reset the control head. */
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (offset != 0)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
+ }
+
+ /* Even if the match is empty, we need to reset the control head. */
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+
+ JUMPTO(SLJIT_JUMP, loop);
+ flush_stubs(common);
+
+ compile_backtrackingpath(common, backtrack->top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ set_jumps(backtrack->topbacktracks, LABEL());
+
+ if (framesize < 0)
+ {
+ if (offset != 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ else
+ {
+ if (offset != 0)
+ {
+ /* Last alternative. */
+ if (*cc == OP_KETRPOS)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
+ }
+ }
+
+ if (*cc == OP_KETRPOS)
+ break;
+ ccbegin = cc + 1 + LINK_SIZE;
+ }
+
+/* We don't have to restore the control head in case of a failed match. */
+
+backtrack->topbacktracks = NULL;
+if (!zero)
+ {
+ if (framesize < 0)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
+ else /* TMP2 is set to [private_data_ptr] above. */
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0));
+ }
+
+/* None of them matched. */
+set_jumps(emptymatch, LABEL());
+count_match(common);
+return cc + 1 + LINK_SIZE;
+}
+
+static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_u32 *max, sljit_u32 *exact, PCRE2_SPTR *end)
+{
+int class_len;
+
+*opcode = *cc;
+*exact = 0;
+
+if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
+ {
+ cc++;
+ *type = OP_CHAR;
+ }
+else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
+ {
+ cc++;
+ *type = OP_CHARI;
+ *opcode -= OP_STARI - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
+ {
+ cc++;
+ *type = OP_NOT;
+ *opcode -= OP_NOTSTAR - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
+ {
+ cc++;
+ *type = OP_NOTI;
+ *opcode -= OP_NOTSTARI - OP_STAR;
+ }
+else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
+ {
+ cc++;
+ *opcode -= OP_TYPESTAR - OP_STAR;
+ *type = OP_END;
+ }
+else
+ {
+ SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
+ *type = *opcode;
+ cc++;
+ class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0);
+ *opcode = cc[class_len - 1];
+
+ if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
+ {
+ *opcode -= OP_CRSTAR - OP_STAR;
+ *end = cc + class_len;
+
+ if (*opcode == OP_PLUS || *opcode == OP_MINPLUS)
+ {
+ *exact = 1;
+ *opcode -= OP_PLUS - OP_STAR;
+ }
+ }
+ else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
+ {
+ *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
+ *end = cc + class_len;
+
+ if (*opcode == OP_POSPLUS)
+ {
+ *exact = 1;
+ *opcode = OP_POSSTAR;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
+ *max = GET2(cc, (class_len + IMM2_SIZE));
+ *exact = GET2(cc, class_len);
+
+ if (*max == 0)
+ {
+ if (*opcode == OP_CRPOSRANGE)
+ *opcode = OP_POSSTAR;
+ else
+ *opcode -= OP_CRRANGE - OP_STAR;
+ }
+ else
+ {
+ *max -= *exact;
+ if (*max == 0)
+ *opcode = OP_EXACT;
+ else if (*max == 1)
+ {
+ if (*opcode == OP_CRPOSRANGE)
+ *opcode = OP_POSQUERY;
+ else
+ *opcode -= OP_CRRANGE - OP_QUERY;
+ }
+ else
+ {
+ if (*opcode == OP_CRPOSRANGE)
+ *opcode = OP_POSUPTO;
+ else
+ *opcode -= OP_CRRANGE - OP_UPTO;
+ }
+ }
+ *end = cc + class_len + 2 * IMM2_SIZE;
+ }
+ return cc;
+ }
+
+switch(*opcode)
+ {
+ case OP_EXACT:
+ *exact = GET2(cc, 0);
+ cc += IMM2_SIZE;
+ break;
+
+ case OP_PLUS:
+ case OP_MINPLUS:
+ *exact = 1;
+ *opcode -= OP_PLUS - OP_STAR;
+ break;
+
+ case OP_POSPLUS:
+ *exact = 1;
+ *opcode = OP_POSSTAR;
+ break;
+
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ *max = GET2(cc, 0);
+ cc += IMM2_SIZE;
+ break;
+ }
+
+if (*type == OP_END)
+ {
+ *type = *cc;
+ *end = next_opcode(common, cc);
+ cc++;
+ return cc;
+ }
+
+*end = cc + 1;
+#ifdef SUPPORT_UNICODE
+if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
+#endif
+return cc;
+}
+
+static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+PCRE2_UCHAR opcode;
+PCRE2_UCHAR type;
+sljit_u32 max = 0, exact;
+BOOL fast_fail;
+sljit_s32 fast_str_ptr;
+BOOL charpos_enabled;
+PCRE2_UCHAR charpos_char;
+unsigned int charpos_othercasebit;
+PCRE2_SPTR end;
+jump_list *no_match = NULL;
+jump_list *no_char1_match = NULL;
+struct sljit_jump *jump = NULL;
+struct sljit_label *label;
+int private_data_ptr = PRIVATE_DATA(cc);
+int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
+int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
+int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
+int tmp_base, tmp_offset;
+
+PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL);
+
+fast_str_ptr = PRIVATE_DATA(cc + 1);
+fast_fail = TRUE;
+
+SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr);
+
+if (cc == common->fast_forward_bc_ptr)
+ fast_fail = FALSE;
+else if (common->fast_fail_start_ptr == 0)
+ fast_str_ptr = 0;
+
+SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0
+ || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr));
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
+
+if (type != OP_EXTUNI)
+ {
+ tmp_base = TMP3;
+ tmp_offset = 0;
+ }
+else
+ {
+ tmp_base = SLJIT_MEM1(SLJIT_SP);
+ tmp_offset = POSSESSIVE0;
+ }
+
+if (fast_fail && fast_str_ptr != 0)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr));
+
+/* Handle fixed part first. */
+if (exact > 1)
+ {
+ SLJIT_ASSERT(fast_str_ptr == 0);
+ if (common->mode == PCRE2_JIT_COMPLETE
+#ifdef SUPPORT_UNICODE
+ && !common->utf
+#endif
+ )
+ {
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact));
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0));
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ }
+ }
+else if (exact == 1)
+ compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_UPTO:
+ SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR);
+
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ SLJIT_ASSERT(private_data_ptr == 0);
+ SLJIT_ASSERT(fast_str_ptr == 0);
+
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+
+ if (opcode == OP_UPTO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max);
+
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
+ if (opcode == OP_UPTO)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ jump = JUMP(SLJIT_ZERO);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
+ }
+
+ /* We cannot use TMP3 because of this allocate_stack. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ if (jump != NULL)
+ JUMPHERE(jump);
+ }
+ else
+ {
+ charpos_enabled = FALSE;
+ charpos_char = 0;
+ charpos_othercasebit = 0;
+
+ if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))
+ {
+ charpos_enabled = TRUE;
+#ifdef SUPPORT_UNICODE
+ charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);
+#endif
+ if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))
+ {
+ charpos_othercasebit = char_get_othercase_bit(common, end + 1);
+ if (charpos_othercasebit == 0)
+ charpos_enabled = FALSE;
+ }
+
+ if (charpos_enabled)
+ {
+ charpos_char = end[1];
+ /* Consumpe the OP_CHAR opcode. */
+ end += 2;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);
+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);
+ if ((charpos_othercasebit & 0x100) != 0)
+ charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;
+#endif
+ if (charpos_othercasebit != 0)
+ charpos_char |= charpos_othercasebit;
+
+ BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE;
+ BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;
+ BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;
+ }
+ }
+
+ if (charpos_enabled)
+ {
+ if (opcode == OP_UPTO)
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1);
+
+ /* Search the first instance of charpos_char. */
+ jump = JUMP(SLJIT_JUMP);
+ label = LABEL();
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
+ }
+ compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
+
+ detect_partial_match(common, &backtrack->topbacktracks);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (charpos_othercasebit != 0)
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
+
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
+ }
+
+ /* Search the last instance of charpos_char. */
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ detect_partial_match(common, &no_match);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (charpos_othercasebit != 0)
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
+ if (opcode == OP_STAR)
+ {
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ }
+ else
+ {
+ jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
+
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, label);
+
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ }
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ else if (common->utf)
+ {
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
+
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+
+ if (opcode == OP_UPTO)
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, label);
+
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ }
+#endif
+ else
+ {
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
+
+ OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+ if (opcode == OP_UPTO)
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+
+ label = LABEL();
+ detect_partial_match(common, &no_match);
+ compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+ else
+ JUMPTO(SLJIT_JUMP, label);
+
+ set_jumps(no_char1_match, LABEL());
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ }
+ }
+ BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
+ break;
+
+ case OP_MINSTAR:
+ if (private_data_ptr == 0)
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ break;
+
+ case OP_MINUPTO:
+ SLJIT_ASSERT(fast_str_ptr == 0);
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1);
+ BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
+ break;
+
+ case OP_QUERY:
+ case OP_MINQUERY:
+ SLJIT_ASSERT(fast_str_ptr == 0);
+ if (private_data_ptr == 0)
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ if (opcode == OP_QUERY)
+ compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
+ BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
+ break;
+
+ case OP_EXACT:
+ break;
+
+ case OP_POSSTAR:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ {
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ break;
+ }
+#endif
+ label = LABEL();
+ detect_partial_match(common, &no_match);
+ compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
+ JUMPTO(SLJIT_JUMP, label);
+ set_jumps(no_char1_match, LABEL());
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ set_jumps(no_match, LABEL());
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ break;
+
+ case OP_POSUPTO:
+ SLJIT_ASSERT(fast_str_ptr == 0);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
+ break;
+ }
+#endif
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+ label = LABEL();
+ detect_partial_match(common, &no_match);
+ compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ set_jumps(no_char1_match, LABEL());
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ set_jumps(no_match, LABEL());
+ break;
+
+ case OP_POSQUERY:
+ SLJIT_ASSERT(fast_str_ptr == 0);
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
+ compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+count_match(common);
+return end;
+}
+
+static SLJIT_INLINE PCRE2_SPTR compile_fail_accept_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+
+PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
+
+if (*cc == OP_FAIL)
+ {
+ add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
+ return cc + 1;
+ }
+
+if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
+ {
+ /* No need to check notempty conditions. */
+ if (common->accept_label == NULL)
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->accept_label);
+ return cc + 1;
+ }
+
+if (common->accept_label == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));
+else
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO));
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
+if (common->accept_label == NULL)
+ add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO));
+else
+ JUMPTO(SLJIT_ZERO, common->accept_label);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+if (common->accept_label == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
+else
+ CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
+return cc + 1;
+}
+
+static SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *common, PCRE2_SPTR cc)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1);
+BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
+
+/* Data will be discarded anyway... */
+if (common->currententry != NULL)
+ return cc + 1 + IMM2_SIZE;
+
+if (!optimized_cbracket)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset));
+offset <<= 1;
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
+if (!optimized_cbracket)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
+return cc + 1 + IMM2_SIZE;
+}
+
+static SLJIT_INLINE PCRE2_SPTR compile_control_verb_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+PCRE2_UCHAR opcode = *cc;
+PCRE2_SPTR ccend = cc + 1;
+
+if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
+ ccend += 2 + cc[1];
+
+PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
+
+if (opcode == OP_SKIP)
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ return ccend;
+ }
+
+if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
+ }
+
+return ccend;
+}
+
+static PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP };
+
+static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+BOOL needs_control_head;
+int size;
+
+PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
+common->then_trap = BACKTRACK_AS(then_trap_backtrack);
+BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
+BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
+BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
+
+size = BACKTRACK_AS(then_trap_backtrack)->framesize;
+size = 3 + (size < 0 ? 0 : size);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+allocate_stack(common, size);
+if (size > 3)
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
+else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
+
+size = BACKTRACK_AS(then_trap_backtrack)->framesize;
+if (size >= 0)
+ init_frame(common, cc, ccend, size - 1, 0, FALSE);
+}
+
+static void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+BOOL has_then_trap = FALSE;
+then_trap_backtrack *save_then_trap = NULL;
+
+SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
+
+if (common->has_then && common->then_offsets[cc - common->start] != 0)
+ {
+ SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
+ has_then_trap = TRUE;
+ save_then_trap = common->then_trap;
+ /* Tail item on backtrack. */
+ compile_then_trap_matchingpath(common, cc, ccend, parent);
+ }
+
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_REVERSE:
+ cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ break;
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_NOTPROP:
+ case OP_PROP:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_NOT:
+ case OP_NOTI:
+ cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
+ break;
+
+ case OP_SET_SOM:
+ PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ cc++;
+ break;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ else
+ cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ cc = compile_iterator_matchingpath(common, cc, parent);
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE)
+ cc = compile_iterator_matchingpath(common, cc, parent);
+ else
+ cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
+ break;
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ case OP_XCLASS:
+ if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
+ cc = compile_iterator_matchingpath(common, cc, parent);
+ else
+ cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
+ break;
+#endif
+
+ case OP_REF:
+ case OP_REFI:
+ if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)
+ cc = compile_ref_iterator_matchingpath(common, cc, parent);
+ else
+ {
+ compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
+ cc += 1 + IMM2_SIZE;
+ }
+ break;
+
+ case OP_DNREF:
+ case OP_DNREFI:
+ if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
+ cc = compile_ref_iterator_matchingpath(common, cc, parent);
+ else
+ {
+ compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
+ cc += 1 + 2 * IMM2_SIZE;
+ }
+ break;
+
+ case OP_RECURSE:
+ cc = compile_recurse_matchingpath(common, cc, parent);
+ break;
+
+ case OP_CALLOUT:
+ case OP_CALLOUT_STR:
+ cc = compile_callout_matchingpath(common, cc, parent);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
+ cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
+ break;
+
+ case OP_BRAMINZERO:
+ PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
+ cc = bracketend(cc + 1);
+ if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
+ }
+ BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
+ count_match(common);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ cc = compile_bracket_matchingpath(common, cc, parent);
+ break;
+
+ case OP_BRAZERO:
+ if (cc[1] > OP_ASSERTBACK_NOT)
+ cc = compile_bracket_matchingpath(common, cc, parent);
+ else
+ {
+ PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
+ cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
+ }
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ cc = compile_bracketpos_matchingpath(common, cc, parent);
+ break;
+
+ case OP_MARK:
+ PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
+ SLJIT_ASSERT(common->mark_ptr != 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
+ allocate_stack(common, common->has_skip_arg ? 5 : 1);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
+ if (common->has_skip_arg)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ }
+ cc += 1 + 2 + cc[1];
+ break;
+
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ case OP_THEN:
+ case OP_THEN_ARG:
+ case OP_COMMIT:
+ cc = compile_control_verb_matchingpath(common, cc, parent);
+ break;
+
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ cc = compile_fail_accept_matchingpath(common, cc, parent);
+ break;
+
+ case OP_CLOSE:
+ cc = compile_close_matchingpath(common, cc);
+ break;
+
+ case OP_SKIPZERO:
+ cc = bracketend(cc + 1);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return;
+ }
+ if (cc == NULL)
+ return;
+ }
+
+if (has_then_trap)
+ {
+ /* Head item on backtrack. */
+ PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
+ BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
+ BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
+ common->then_trap = save_then_trap;
+ }
+SLJIT_ASSERT(cc == ccend);
+}
+
+#undef PUSH_BACKTRACK
+#undef PUSH_BACKTRACK_NOVALUE
+#undef BACKTRACK_AS
+
+#define COMPILE_BACKTRACKINGPATH(current) \
+ do \
+ { \
+ compile_backtrackingpath(common, (current)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ } \
+ while (0)
+
+#define CURRENT_AS(type) ((type *)current)
+
+static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+PCRE2_SPTR cc = current->cc;
+PCRE2_UCHAR opcode;
+PCRE2_UCHAR type;
+sljit_u32 max = 0, exact;
+struct sljit_label *label = NULL;
+struct sljit_jump *jump = NULL;
+jump_list *jumplist = NULL;
+PCRE2_SPTR end;
+int private_data_ptr = PRIVATE_DATA(cc);
+int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
+int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
+int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_UPTO:
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ SLJIT_ASSERT(private_data_ptr == 0);
+ set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+ }
+ else
+ {
+ if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ OP1(SLJIT_MOV, TMP2, 0, base, offset1);
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+ jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+ label = LABEL();
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0)
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit);
+ CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+ skip_char_back(common);
+ CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);
+ skip_char_back(common);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+ }
+ JUMPHERE(jump);
+ if (private_data_ptr == 0)
+ free_stack(common, 2);
+ }
+ break;
+
+ case OP_MINSTAR:
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+ set_jumps(jumplist, LABEL());
+ if (private_data_ptr == 0)
+ free_stack(common, 1);
+ break;
+
+ case OP_MINUPTO:
+ OP1(SLJIT_MOV, TMP1, 0, base, offset1);
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO));
+
+ OP1(SLJIT_MOV, base, offset1, TMP1, 0);
+ compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+
+ set_jumps(jumplist, LABEL());
+ if (private_data_ptr == 0)
+ free_stack(common, 2);
+ break;
+
+ case OP_QUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+ JUMPHERE(jump);
+ if (private_data_ptr == 0)
+ free_stack(common, 1);
+ break;
+
+ case OP_MINQUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
+ set_jumps(jumplist, LABEL());
+ JUMPHERE(jump);
+ if (private_data_ptr == 0)
+ free_stack(common, 1);
+ break;
+
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+set_jumps(current->topbacktracks, LABEL());
+}
+
+static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+PCRE2_SPTR cc = current->cc;
+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
+PCRE2_UCHAR type;
+
+type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
+
+if ((type & 0x1) == 0)
+ {
+ /* Maximize case. */
+ set_jumps(current->topbacktracks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
+ return;
+ }
+
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
+set_jumps(current->topbacktracks, LABEL());
+free_stack(common, ref ? 2 : 3);
+}
+
+static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+
+if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
+ compile_backtrackingpath(common, current->top);
+set_jumps(current->topbacktracks, LABEL());
+if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
+ return;
+
+if (common->has_set_som && common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
+ }
+else if (common->has_set_som || common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
+ }
+}
+
+static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+PCRE2_SPTR cc = current->cc;
+PCRE2_UCHAR bra = OP_BRA;
+struct sljit_jump *brajump = NULL;
+
+SLJIT_ASSERT(*cc != OP_BRAMINZERO);
+if (*cc == OP_BRAZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ SLJIT_ASSERT(current->topbacktracks == NULL);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+
+if (CURRENT_AS(assert_backtrack)->framesize < 0)
+ {
+ set_jumps(current->topbacktracks, LABEL());
+
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
+ free_stack(common, 1);
+ }
+ return;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
+ free_stack(common, 1);
+ return;
+ }
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw));
+
+ set_jumps(current->topbacktracks, LABEL());
+ }
+else
+ set_jumps(current->topbacktracks, LABEL());
+
+if (bra == OP_BRAZERO)
+ {
+ /* We know there is enough place on the stack. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
+ JUMPHERE(brajump);
+ }
+}
+
+static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+int opcode, stacksize, alt_count, alt_max;
+int offset = 0;
+int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
+int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
+PCRE2_SPTR cc = current->cc;
+PCRE2_SPTR ccbegin;
+PCRE2_SPTR ccprev;
+PCRE2_UCHAR bra = OP_BRA;
+PCRE2_UCHAR ket;
+assert_backtrack *assert;
+sljit_uw *next_update_addr = NULL;
+BOOL has_alternatives;
+BOOL needs_control_head = FALSE;
+struct sljit_jump *brazero = NULL;
+struct sljit_jump *alt1 = NULL;
+struct sljit_jump *alt2 = NULL;
+struct sljit_jump *once = NULL;
+struct sljit_jump *cond = NULL;
+struct sljit_label *rmin_label = NULL;
+struct sljit_label *exact_label = NULL;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+opcode = *cc;
+ccbegin = bracketend(cc) - 1 - LINK_SIZE;
+ket = *ccbegin;
+if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
+ {
+ repeat_ptr = PRIVATE_DATA(ccbegin);
+ repeat_type = PRIVATE_DATA(ccbegin + 2);
+ repeat_count = PRIVATE_DATA(ccbegin + 3);
+ SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
+ if (repeat_type == OP_UPTO)
+ ket = OP_KETRMAX;
+ if (repeat_type == OP_MINUPTO)
+ ket = OP_KETRMIN;
+ }
+ccbegin = cc;
+cc += GET(cc, 1);
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
+
+/* Decoding the needs_control_head in framesize. */
+if (opcode == OP_ONCE)
+ {
+ needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
+ CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
+ }
+
+if (ket != OP_KET && repeat_type != 0)
+ {
+ /* TMP1 is used in OP_KETRMIN below. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ if (repeat_type == OP_UPTO)
+ OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+ }
+else if (ket == OP_KETRMIN)
+ {
+ if (bra != OP_BRAMINZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (repeat_type != 0)
+ {
+ /* TMP1 was set a few lines above. */
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
+ /* Drop STR_PTR for non-greedy plus quantifier. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else if (opcode >= OP_SBRA || opcode == OP_ONCE)
+ {
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
+ }
+ /* Drop STR_PTR for non-greedy plus quantifier. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
+ }
+ rmin_label = LABEL();
+ if (repeat_type != 0)
+ OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+else if (repeat_type == OP_EXACT)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
+ exact_label = LABEL();
+ }
+
+if (offset != 0)
+ {
+ if (common->capture_last_ptr != 0)
+ {
+ SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
+ free_stack(common, 3);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
+ }
+ else if (common->optimized_cbracket[offset >> 1] == 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
+ }
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_ONCE))
+ {
+ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ once = JUMP(SLJIT_JUMP);
+ }
+else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ if (has_alternatives)
+ {
+ /* Always exactly one alternative. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+
+ alt_max = 2;
+ alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
+ }
+ }
+else if (has_alternatives)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+
+ if (alt_max > 4)
+ {
+ /* Table jump if alt_max is greater than 4. */
+ next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
+ if (SLJIT_UNLIKELY(next_update_addr == NULL))
+ return;
+ sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
+ add_label_addr(common, next_update_addr++);
+ }
+ else
+ {
+ if (alt_max == 4)
+ alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
+ alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
+ }
+ }
+
+COMPILE_BACKTRACKINGPATH(current->top);
+if (current->topbacktracks)
+ set_jumps(current->topbacktracks, LABEL());
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ /* Conditional block always has at most one alternative. */
+ if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ assert = CURRENT_AS(bracket_backtrack)->u.assert;
+ if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
+ }
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
+ }
+ else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
+ }
+ else
+ SLJIT_ASSERT(!has_alternatives);
+ }
+
+if (has_alternatives)
+ {
+ alt_count = sizeof(sljit_uw);
+ do
+ {
+ current->top = NULL;
+ current->topbacktracks = NULL;
+ current->nextbacktracks = NULL;
+ /* Conditional blocks always have an additional alternative, even if it is empty. */
+ if (*cc == OP_ALT)
+ {
+ ccprev = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ if (opcode != OP_COND && opcode != OP_SCOND)
+ {
+ if (opcode != OP_ONCE)
+ {
+ if (private_data_ptr != 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
+ }
+ compile_matchingpath(common, ccprev, cc, current);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+ }
+
+ /* Instructions after the current alternative is successfully matched. */
+ /* There is a similar code in compile_bracket_matchingpath. */
+ if (opcode == OP_ONCE)
+ match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
+
+ stacksize = 0;
+ if (repeat_type == OP_MINUPTO)
+ {
+ /* We need to preserve the counter. TMP2 will be used below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
+ stacksize++;
+ }
+ if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+ if (offset != 0)
+ {
+ if (common->capture_last_ptr != 0)
+ stacksize++;
+ if (common->optimized_cbracket[offset >> 1] == 0)
+ stacksize += 2;
+ }
+ if (opcode != OP_ONCE)
+ stacksize++;
+
+ if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+ stacksize = 0;
+ if (repeat_type == OP_MINUPTO)
+ {
+ /* TMP2 was set above. */
+ OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
+ stacksize++;
+ }
+
+ if (ket != OP_KET || bra != OP_BRA)
+ {
+ if (ket != OP_KET)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+ if (offset != 0)
+ stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
+
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
+
+ if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
+ {
+ /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
+ SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
+ }
+
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
+
+ if (opcode != OP_ONCE)
+ {
+ if (alt_max > 4)
+ add_label_addr(common, next_update_addr++);
+ else
+ {
+ if (alt_count != 2 * sizeof(sljit_uw))
+ {
+ JUMPHERE(alt1);
+ if (alt_max == 3 && alt_count == sizeof(sljit_uw))
+ alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
+ }
+ else
+ {
+ JUMPHERE(alt2);
+ if (alt_max == 4)
+ alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
+ }
+ }
+ alt_count += sizeof(sljit_uw);
+ }
+
+ COMPILE_BACKTRACKINGPATH(current->top);
+ if (current->topbacktracks)
+ set_jumps(current->topbacktracks, LABEL());
+ SLJIT_ASSERT(!current->nextbacktracks);
+ }
+ while (*cc == OP_ALT);
+
+ if (cond != NULL)
+ {
+ SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
+ assert = CURRENT_AS(bracket_backtrack)->u.assert;
+ if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
+ }
+ JUMPHERE(cond);
+ }
+
+ /* Free the STR_PTR. */
+ if (private_data_ptr == 0)
+ free_stack(common, 1);
+ }
+
+if (offset != 0)
+ {
+ /* Using both tmp register is better for instruction scheduling. */
+ if (common->optimized_cbracket[offset >> 1] != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
+ }
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ }
+else if (opcode == OP_ONCE)
+ {
+ cc = ccbegin + GET(ccbegin, 1);
+ stacksize = needs_control_head ? 1 : 0;
+
+ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
+ {
+ /* Reset head and drop saved frame. */
+ stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
+ }
+ else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
+ {
+ /* The STR_PTR must be released. */
+ stacksize++;
+ }
+
+ if (stacksize > 0)
+ free_stack(common, stacksize);
+
+ JUMPHERE(once);
+ /* Restore previous private_data_ptr */
+ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw));
+ else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* See the comment below. */
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
+ }
+ }
+
+if (repeat_type == OP_EXACT)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
+ CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
+ }
+else if (ket == OP_KETRMAX)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (bra != OP_BRAZERO)
+ free_stack(common, 1);
+
+ CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
+ JUMPHERE(brazero);
+ free_stack(common, 1);
+ }
+ }
+else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ /* OP_ONCE removes everything in case of a backtrack, so we don't
+ need to explicitly release the STR_PTR. The extra release would
+ affect badly the free_stack(2) above. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
+ if (opcode == OP_ONCE)
+ free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
+ else if (bra == OP_BRAMINZERO)
+ free_stack(common, 1);
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
+ JUMPHERE(brazero);
+ }
+}
+
+static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+int offset;
+struct sljit_jump *jump;
+
+if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
+ {
+ if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
+ {
+ offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
+ }
+ set_jumps(current->topbacktracks, LABEL());
+ free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
+ return;
+ }
+
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
+add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+
+if (current->topbacktracks)
+ {
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(current->topbacktracks, LABEL());
+ /* Drop the stack frame. */
+ free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
+ JUMPHERE(jump);
+ }
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
+}
+
+static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+assert_backtrack backtrack;
+
+current->top = NULL;
+current->topbacktracks = NULL;
+current->nextbacktracks = NULL;
+if (current->cc[1] > OP_ASSERTBACK_NOT)
+ {
+ /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
+ compile_bracket_matchingpath(common, current->cc, current);
+ compile_bracket_backtrackingpath(common, current->top);
+ }
+else
+ {
+ memset(&backtrack, 0, sizeof(backtrack));
+ backtrack.common.cc = current->cc;
+ backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
+ /* Manual call of compile_assert_matchingpath. */
+ compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
+ }
+SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
+}
+
+static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+PCRE2_UCHAR opcode = *current->cc;
+struct sljit_label *loop;
+struct sljit_jump *jump;
+
+if (opcode == OP_THEN || opcode == OP_THEN_ARG)
+ {
+ if (common->then_trap != NULL)
+ {
+ SLJIT_ASSERT(common->control_head_ptr != 0);
+
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
+ jump = JUMP(SLJIT_JUMP);
+
+ loop = LABEL();
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
+ JUMPHERE(jump);
+ CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
+ CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
+ add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
+ return;
+ }
+ else if (common->positive_assert)
+ {
+ add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
+ return;
+ }
+ }
+
+if (common->local_exit)
+ {
+ if (common->quit_label == NULL)
+ add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->quit_label);
+ return;
+ }
+
+if (opcode == OP_SKIP_ARG)
+ {
+ SLJIT_ASSERT(common->control_head_ptr != 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
+ sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
+ add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
+ return;
+ }
+
+if (opcode == OP_SKIP)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
+add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
+}
+
+static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+int size;
+
+if (CURRENT_AS(then_trap_backtrack)->then_trap)
+ {
+ common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
+ return;
+ }
+
+size = CURRENT_AS(then_trap_backtrack)->framesize;
+size = 3 + (size < 0 ? 0 : size);
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
+free_stack(common, size);
+jump = JUMP(SLJIT_JUMP);
+
+set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
+/* STACK_TOP is set by THEN. */
+if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+free_stack(common, 3);
+
+JUMPHERE(jump);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
+}
+
+static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+then_trap_backtrack *save_then_trap = common->then_trap;
+
+while (current)
+ {
+ if (current->nextbacktracks != NULL)
+ set_jumps(current->nextbacktracks, LABEL());
+ switch(*current->cc)
+ {
+ case OP_SET_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+#endif
+ compile_iterator_backtrackingpath(common, current);
+ break;
+
+ case OP_REF:
+ case OP_REFI:
+ case OP_DNREF:
+ case OP_DNREFI:
+ compile_ref_iterator_backtrackingpath(common, current);
+ break;
+
+ case OP_RECURSE:
+ compile_recurse_backtrackingpath(common, current);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ compile_assert_backtrackingpath(common, current);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ compile_bracket_backtrackingpath(common, current);
+ break;
+
+ case OP_BRAZERO:
+ if (current->cc[1] > OP_ASSERTBACK_NOT)
+ compile_bracket_backtrackingpath(common, current);
+ else
+ compile_assert_backtrackingpath(common, current);
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ compile_bracketpos_backtrackingpath(common, current);
+ break;
+
+ case OP_BRAMINZERO:
+ compile_braminzero_backtrackingpath(common, current);
+ break;
+
+ case OP_MARK:
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
+ if (common->has_skip_arg)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, common->has_skip_arg ? 5 : 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
+ if (common->has_skip_arg)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
+ break;
+
+ case OP_THEN:
+ case OP_THEN_ARG:
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ compile_control_verb_backtrackingpath(common, current);
+ break;
+
+ case OP_COMMIT:
+ if (!common->local_exit)
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
+ if (common->quit_label == NULL)
+ add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->quit_label);
+ break;
+
+ case OP_CALLOUT:
+ case OP_CALLOUT_STR:
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ set_jumps(current->topbacktracks, LABEL());
+ break;
+
+ case OP_THEN_TRAP:
+ /* A virtual opcode for then traps. */
+ compile_then_trap_backtrackingpath(common, current);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ current = current->prev;
+ }
+common->then_trap = save_then_trap;
+}
+
+static SLJIT_INLINE void compile_recurse(compiler_common *common)
+{
+DEFINE_COMPILER;
+PCRE2_SPTR cc = common->start + common->currententry->start;
+PCRE2_SPTR ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
+PCRE2_SPTR ccend = bracketend(cc) - (1 + LINK_SIZE);
+BOOL needs_control_head;
+int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
+int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
+int alternativesize;
+BOOL needs_frame;
+backtrack_common altbacktrack;
+struct sljit_jump *jump;
+
+/* Recurse captures then. */
+common->then_trap = NULL;
+
+SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
+needs_frame = framesize >= 0;
+if (!needs_frame)
+ framesize = 0;
+alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
+
+SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
+common->currententry->entry = LABEL();
+set_jumps(common->currententry->calls, common->currententry->entry);
+
+sljit_emit_fast_enter(compiler, TMP2, 0);
+count_match(common);
+allocate_stack(common, private_data_size + framesize + alternativesize);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
+copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
+if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);
+if (needs_frame)
+ init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
+
+if (alternativesize > 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+memset(&altbacktrack, 0, sizeof(backtrack_common));
+common->quit_label = NULL;
+common->accept_label = NULL;
+common->quit = NULL;
+common->accept = NULL;
+altbacktrack.cc = ccbegin;
+cc += GET(cc, 1);
+while (1)
+ {
+ altbacktrack.top = NULL;
+ altbacktrack.topbacktracks = NULL;
+
+ if (altbacktrack.cc != ccbegin)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+
+ compile_backtrackingpath(common, altbacktrack.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+ set_jumps(altbacktrack.topbacktracks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ altbacktrack.cc = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+
+/* None of them matched. */
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
+jump = JUMP(SLJIT_JUMP);
+
+if (common->quit != NULL)
+ {
+ set_jumps(common->quit, LABEL());
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
+ if (needs_frame)
+ {
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
+ }
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
+ common->quit = NULL;
+ add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
+ }
+
+set_jumps(common->accept, LABEL());
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
+if (needs_frame)
+ {
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
+ }
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
+
+JUMPHERE(jump);
+if (common->quit != NULL)
+ set_jumps(common->quit, LABEL());
+copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
+free_stack(common, private_data_size + framesize + alternativesize);
+if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
+ }
+else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP2, 0);
+ }
+sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
+}
+
+#undef COMPILE_BACKTRACKINGPATH
+#undef CURRENT_AS
+
+static int jit_compile(pcre2_code *code, sljit_u32 mode)
+{
+pcre2_real_code *re = (pcre2_real_code *)code;
+struct sljit_compiler *compiler;
+backtrack_common rootbacktrack;
+compiler_common common_data;
+compiler_common *common = &common_data;
+const sljit_u8 *tables = re->tables;
+void *allocator_data = &re->memctl;
+int private_data_size;
+PCRE2_SPTR ccend;
+executable_functions *functions;
+void *executable_func;
+sljit_uw executable_size;
+sljit_uw total_length;
+label_addr_list *label_addr;
+struct sljit_label *mainloop_label = NULL;
+struct sljit_label *continue_match_label;
+struct sljit_label *empty_match_found_label = NULL;
+struct sljit_label *empty_match_backtrack_label = NULL;
+struct sljit_label *reset_match_label;
+struct sljit_label *quit_label;
+struct sljit_jump *jump;
+struct sljit_jump *minlength_check_failed = NULL;
+struct sljit_jump *reqbyte_notfound = NULL;
+struct sljit_jump *empty_match = NULL;
+
+SLJIT_ASSERT(tables);
+
+memset(&rootbacktrack, 0, sizeof(backtrack_common));
+memset(common, 0, sizeof(compiler_common));
+common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code));
+rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size;
+
+common->start = rootbacktrack.cc;
+common->read_only_data_head = NULL;
+common->fcc = tables + fcc_offset;
+common->lcc = (sljit_sw)(tables + lcc_offset);
+common->mode = mode;
+common->might_be_empty = re->minlength == 0;
+common->nltype = NLTYPE_FIXED;
+switch(re->newline_convention)
+ {
+ case PCRE2_NEWLINE_CR: common->newline = CHAR_CR; break;
+ case PCRE2_NEWLINE_LF: common->newline = CHAR_NL; break;
+ case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
+ case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
+ default: return PCRE2_ERROR_INTERNAL;
+ }
+common->nlmax = READ_CHAR_MAX;
+common->nlmin = 0;
+if (re->bsr_convention == PCRE2_BSR_UNICODE)
+ common->bsr_nltype = NLTYPE_ANY;
+else if (re->bsr_convention == PCRE2_BSR_ANYCRLF)
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+else
+ {
+#ifdef BSR_ANYCRLF
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+#else
+ common->bsr_nltype = NLTYPE_ANY;
+#endif
+ }
+common->bsr_nlmax = READ_CHAR_MAX;
+common->bsr_nlmin = 0;
+common->endonly = (re->overall_options & PCRE2_DOLLAR_ENDONLY) != 0;
+common->ctypes = (sljit_sw)(tables + ctypes_offset);
+common->name_count = re->name_count;
+common->name_entry_size = re->name_entry_size;
+common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0;
+common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0;
+#ifdef SUPPORT_UNICODE
+/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
+common->utf = (re->overall_options & PCRE2_UTF) != 0;
+common->use_ucp = (re->overall_options & PCRE2_UCP) != 0;
+if (common->utf)
+ {
+ if (common->nltype == NLTYPE_ANY)
+ common->nlmax = 0x2029;
+ else if (common->nltype == NLTYPE_ANYCRLF)
+ common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
+ else
+ {
+ /* We only care about the first newline character. */
+ common->nlmax = common->newline & 0xff;
+ }
+
+ if (common->nltype == NLTYPE_FIXED)
+ common->nlmin = common->newline & 0xff;
+ else
+ common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
+
+ if (common->bsr_nltype == NLTYPE_ANY)
+ common->bsr_nlmax = 0x2029;
+ else
+ common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
+ common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
+ }
+#endif /* SUPPORT_UNICODE */
+ccend = bracketend(common->start);
+
+/* Calculate the local space size on the stack. */
+common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
+common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data);
+if (!common->optimized_cbracket)
+ return PCRE2_ERROR_NOMEMORY;
+#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
+memset(common->optimized_cbracket, 0, re->top_bracket + 1);
+#else
+memset(common->optimized_cbracket, 1, re->top_bracket + 1);
+#endif
+
+SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
+#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
+common->capture_last_ptr = common->ovector_start;
+common->ovector_start += sizeof(sljit_sw);
+#endif
+if (!check_opcode_types(common, common->start, ccend))
+ {
+ SLJIT_FREE(common->optimized_cbracket, allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+
+/* Checking flags and updating ovector_start. */
+if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
+ {
+ common->req_char_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+if (mode != PCRE2_JIT_COMPLETE)
+ {
+ common->start_used_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ if (mode == PCRE2_JIT_PARTIAL_SOFT)
+ {
+ common->hit_start = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+ }
+if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0)
+ {
+ common->match_end_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
+common->control_head_ptr = 1;
+#endif
+if (common->control_head_ptr != 0)
+ {
+ common->control_head_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+if (common->has_set_som)
+ {
+ /* Saving the real start pointer is necessary. */
+ common->start_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+
+/* Aligning ovector to even number of sljit words. */
+if ((common->ovector_start & sizeof(sljit_sw)) != 0)
+ common->ovector_start += sizeof(sljit_sw);
+
+if (common->start_ptr == 0)
+ common->start_ptr = OVECTOR(0);
+
+/* Capturing brackets cannot be optimized if callouts are allowed. */
+if (common->capture_last_ptr != 0)
+ memset(common->optimized_cbracket, 0, re->top_bracket + 1);
+
+SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
+common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
+
+total_length = ccend - common->start;
+common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);
+if (!common->private_data_ptrs)
+ {
+ SLJIT_FREE(common->optimized_cbracket, allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32));
+
+private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
+set_private_data_ptrs(common, &private_data_size, ccend);
+if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
+ {
+ if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back)
+ detect_fast_fail(common, common->start, &private_data_size, 4);
+ }
+
+SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr);
+
+if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
+ {
+ SLJIT_FREE(common->private_data_ptrs, allocator_data);
+ SLJIT_FREE(common->optimized_cbracket, allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+
+if (common->has_then)
+ {
+ common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length);
+ memset(common->then_offsets, 0, total_length);
+ set_then_offsets(common, common->start, NULL);
+ }
+
+compiler = sljit_create_compiler(allocator_data);
+if (!compiler)
+ {
+ SLJIT_FREE(common->optimized_cbracket, allocator_data);
+ SLJIT_FREE(common->private_data_ptrs, allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+common->compiler = compiler;
+
+/* Main pcre_jit_exec entry. */
+sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size);
+
+/* Register init. */
+reset_ovector(common, (re->top_bracket + 1) * 2);
+if (common->req_char_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0);
+
+OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0);
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
+
+if (common->fast_fail_start_ptr < common->fast_fail_end_ptr)
+ reset_fast_fail(common);
+
+if (mode == PCRE2_JIT_PARTIAL_SOFT)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
+if (common->control_head_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
+
+/* Main part of the matching */
+if ((re->overall_options & PCRE2_ANCHORED) == 0)
+ {
+ mainloop_label = mainloop_entry(common, (re->flags & PCRE2_HASCRORLF) != 0, re->overall_options);
+ continue_match_label = LABEL();
+ /* Forward search if possible. */
+ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
+ {
+ if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common))
+ ;
+ else if ((re->flags & PCRE2_FIRSTSET) != 0)
+ fast_forward_first_char(common, (PCRE2_UCHAR)(re->first_codeunit), (re->flags & PCRE2_FIRSTCASELESS) != 0);
+ else if ((re->flags & PCRE2_STARTLINE) != 0)
+ fast_forward_newline(common);
+ else if ((re->flags & PCRE2_FIRSTMAPSET) != 0)
+ fast_forward_start_bits(common, re->start_bitmap);
+ }
+ }
+else
+ continue_match_label = LABEL();
+
+if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength));
+ minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);
+ }
+if (common->req_char_ptr != 0)
+ reqbyte_notfound = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0);
+
+/* Store the current STR_PTR in OVECTOR(0). */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
+/* Copy the limit of allowed recursions. */
+OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);
+if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0);
+if (common->fast_forward_bc_ptr != NULL)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0);
+
+if (common->start_ptr != OVECTOR(0))
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);
+
+/* Copy the beginning of the string. */
+if (mode == PCRE2_JIT_PARTIAL_SOFT)
+ {
+ jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
+else if (mode == PCRE2_JIT_PARTIAL_HARD)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
+
+compile_matchingpath(common, common->start, ccend, &rootbacktrack);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->optimized_cbracket, allocator_data);
+ SLJIT_FREE(common->private_data_ptrs, allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+
+if (common->might_be_empty)
+ {
+ empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
+ empty_match_found_label = LABEL();
+ }
+
+common->accept_label = LABEL();
+if (common->accept != NULL)
+ set_jumps(common->accept, common->accept_label);
+
+/* This means we have a match. Update the ovector. */
+copy_ovector(common, re->top_bracket + 1);
+common->quit_label = common->forced_quit_label = LABEL();
+if (common->quit != NULL)
+ set_jumps(common->quit, common->quit_label);
+if (common->forced_quit != NULL)
+ set_jumps(common->forced_quit, common->forced_quit_label);
+if (minlength_check_failed != NULL)
+ SET_LABEL(minlength_check_failed, common->forced_quit_label);
+sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
+
+if (mode != PCRE2_JIT_COMPLETE)
+ {
+ common->partialmatchlabel = LABEL();
+ set_jumps(common->partialmatch, common->partialmatchlabel);
+ return_with_partial_match(common, common->quit_label);
+ }
+
+if (common->might_be_empty)
+ empty_match_backtrack_label = LABEL();
+compile_backtrackingpath(common, rootbacktrack.top);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->optimized_cbracket, allocator_data);
+ SLJIT_FREE(common->private_data_ptrs, allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+
+SLJIT_ASSERT(rootbacktrack.prev == NULL);
+reset_match_label = LABEL();
+
+if (mode == PCRE2_JIT_PARTIAL_SOFT)
+ {
+ /* Update hit_start only in the first time. */
+ jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0);
+ JUMPHERE(jump);
+ }
+
+/* Check we have remaining characters. */
+if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ }
+
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP),
+ (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1)) : common->start_ptr);
+
+if ((re->overall_options & PCRE2_ANCHORED) == 0)
+ {
+ if (common->ff_newline_shortcut != NULL)
+ {
+ /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */
+ if ((re->overall_options & PCRE2_FIRSTLINE) == 0)
+ {
+ if (common->match_end_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
+ CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut);
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+ }
+ else
+ CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);
+ }
+ }
+ else
+ CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label);
+ }
+
+/* No more remaining characters. */
+if (reqbyte_notfound != NULL)
+ JUMPHERE(reqbyte_notfound);
+
+if (mode == PCRE2_JIT_PARTIAL_SOFT)
+ CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
+
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
+JUMPTO(SLJIT_JUMP, common->quit_label);
+
+flush_stubs(common);
+
+if (common->might_be_empty)
+ {
+ JUMPHERE(empty_match);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
+ JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
+ JUMPTO(SLJIT_ZERO, empty_match_found_label);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
+ JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
+ }
+
+common->fast_forward_bc_ptr = NULL;
+common->fast_fail_start_ptr = 0;
+common->fast_fail_end_ptr = 0;
+common->currententry = common->entries;
+common->local_exit = TRUE;
+quit_label = common->quit_label;
+while (common->currententry != NULL)
+ {
+ /* Might add new entries. */
+ compile_recurse(common);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->optimized_cbracket, allocator_data);
+ SLJIT_FREE(common->private_data_ptrs, allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+ flush_stubs(common);
+ common->currententry = common->currententry->next;
+ }
+common->local_exit = FALSE;
+common->quit_label = quit_label;
+
+/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
+/* This is a (really) rare case. */
+set_jumps(common->stackalloc, LABEL());
+/* RETURN_ADDR is not a saved register. */
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
+OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
+
+sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
+jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+
+/* Allocation failed. */
+JUMPHERE(jump);
+/* We break the return address cache here, but this is a really rare case. */
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_JIT_STACKLIMIT);
+JUMPTO(SLJIT_JUMP, common->quit_label);
+
+/* Call limit reached. */
+set_jumps(common->calllimit, LABEL());
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_MATCHLIMIT);
+JUMPTO(SLJIT_JUMP, common->quit_label);
+
+if (common->revertframes != NULL)
+ {
+ set_jumps(common->revertframes, LABEL());
+ do_revertframes(common);
+ }
+if (common->wordboundary != NULL)
+ {
+ set_jumps(common->wordboundary, LABEL());
+ check_wordboundary(common);
+ }
+if (common->anynewline != NULL)
+ {
+ set_jumps(common->anynewline, LABEL());
+ check_anynewline(common);
+ }
+if (common->hspace != NULL)
+ {
+ set_jumps(common->hspace, LABEL());
+ check_hspace(common);
+ }
+if (common->vspace != NULL)
+ {
+ set_jumps(common->vspace, LABEL());
+ check_vspace(common);
+ }
+if (common->casefulcmp != NULL)
+ {
+ set_jumps(common->casefulcmp, LABEL());
+ do_casefulcmp(common);
+ }
+if (common->caselesscmp != NULL)
+ {
+ set_jumps(common->caselesscmp, LABEL());
+ do_caselesscmp(common);
+ }
+if (common->reset_match != NULL)
+ {
+ set_jumps(common->reset_match, LABEL());
+ do_reset_match(common, (re->top_bracket + 1) * 2);
+ CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
+ JUMPTO(SLJIT_JUMP, reset_match_label);
+ }
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+if (common->utfreadchar != NULL)
+ {
+ set_jumps(common->utfreadchar, LABEL());
+ do_utfreadchar(common);
+ }
+if (common->utfreadchar16 != NULL)
+ {
+ set_jumps(common->utfreadchar16, LABEL());
+ do_utfreadchar16(common);
+ }
+if (common->utfreadtype8 != NULL)
+ {
+ set_jumps(common->utfreadtype8, LABEL());
+ do_utfreadtype8(common);
+ }
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+if (common->getucd != NULL)
+ {
+ set_jumps(common->getucd, LABEL());
+ do_getucd(common);
+ }
+#endif /* SUPPORT_UNICODE */
+
+SLJIT_FREE(common->optimized_cbracket, allocator_data);
+SLJIT_FREE(common->private_data_ptrs, allocator_data);
+
+executable_func = sljit_generate_code(compiler);
+executable_size = sljit_get_generated_code_size(compiler);
+label_addr = common->label_addrs;
+while (label_addr != NULL)
+ {
+ *label_addr->update_addr = sljit_get_label_addr(label_addr->label);
+ label_addr = label_addr->next;
+ }
+sljit_free_compiler(compiler);
+if (executable_func == NULL)
+ {
+ PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+
+/* Reuse the function descriptor if possible. */
+if (re->executable_jit != NULL)
+ functions = (executable_functions *)re->executable_jit;
+else
+ {
+ functions = SLJIT_MALLOC(sizeof(executable_functions), allocator_data);
+ if (functions == NULL)
+ {
+ /* This case is highly unlikely since we just recently
+ freed a lot of memory. Not impossible though. */
+ sljit_free_code(executable_func);
+ PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ return PCRE2_ERROR_NOMEMORY;
+ }
+ memset(functions, 0, sizeof(executable_functions));
+ functions->top_bracket = re->top_bracket + 1;
+ functions->limit_match = re->limit_match;
+ re->executable_jit = functions;
+ }
+
+/* Turn mode into an index. */
+if (mode == PCRE2_JIT_COMPLETE)
+ mode = 0;
+else
+ mode = (mode == PCRE2_JIT_PARTIAL_SOFT) ? 1 : 2;
+
+SLJIT_ASSERT(mode < JIT_NUMBER_OF_COMPILE_MODES);
+functions->executable_funcs[mode] = executable_func;
+functions->read_only_data_heads[mode] = common->read_only_data_head;
+functions->executable_sizes[mode] = executable_size;
+return 0;
+}
+
+#endif
+
+/*************************************************
+* JIT compile a Regular Expression *
+*************************************************/
+
+/* This function used JIT to convert a previously-compiled pattern into machine
+code.
+
+Arguments:
+ code a compiled pattern
+ options JIT option bits
+
+Returns: 0: success or (*NOJIT) was used
+ <0: an error code
+*/
+
+#define PUBLIC_JIT_COMPILE_OPTIONS \
+ (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD)
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_jit_compile(pcre2_code *code, uint32_t options)
+{
+#ifndef SUPPORT_JIT
+
+(void)code;
+(void)options;
+return PCRE2_ERROR_JIT_BADOPTION;
+
+#else /* SUPPORT_JIT */
+
+pcre2_real_code *re = (pcre2_real_code *)code;
+executable_functions *functions;
+int result;
+
+if (code == NULL)
+ return PCRE2_ERROR_NULL;
+
+if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0)
+ return PCRE2_ERROR_JIT_BADOPTION;
+
+if ((re->flags & PCRE2_NOJIT) != 0) return 0;
+
+functions = (executable_functions *)re->executable_jit;
+
+if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL
+ || functions->executable_funcs[0] == NULL)) {
+ result = jit_compile(code, PCRE2_JIT_COMPLETE);
+ if (result != 0)
+ return result;
+ }
+
+if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL
+ || functions->executable_funcs[1] == NULL)) {
+ result = jit_compile(code, PCRE2_JIT_PARTIAL_SOFT);
+ if (result != 0)
+ return result;
+ }
+
+if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL
+ || functions->executable_funcs[2] == NULL)) {
+ result = jit_compile(code, PCRE2_JIT_PARTIAL_HARD);
+ if (result != 0)
+ return result;
+ }
+
+return 0;
+
+#endif /* SUPPORT_JIT */
+}
+
+/* JIT compiler uses an all-in-one approach. This improves security,
+ since the code generator functions are not exported. */
+
+#define INCLUDED_FROM_PCRE2_JIT_COMPILE
+
+#include "pcre2_jit_match.c"
+#include "pcre2_jit_misc.c"
+
+/* End of pcre2_jit_compile.c */
diff --git a/thirdparty/pcre2/src/pcre2_jit_match.c b/thirdparty/pcre2/src/pcre2_jit_match.c
new file mode 100644
index 0000000000..a323971ff3
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_jit_match.c
@@ -0,0 +1,189 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
+#error This file must be included from pcre2_jit_compile.c.
+#endif
+
+#ifdef SUPPORT_JIT
+
+static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func)
+{
+sljit_u8 local_space[MACHINE_STACK_SIZE];
+struct sljit_stack local_stack;
+
+local_stack.top = (sljit_sw)&local_space;
+local_stack.base = local_stack.top;
+local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
+local_stack.max_limit = local_stack.limit;
+arguments->stack = &local_stack;
+return executable_func(arguments);
+}
+
+#endif
+
+
+/*************************************************
+* Do a JIT pattern match *
+*************************************************/
+
+/* This function runs a JIT pattern match.
+
+Arguments:
+ code points to the compiled expression
+ subject points to the subject string
+ length length of subject string (may contain binary zeros)
+ start_offset where to start in the subject string
+ options option bits
+ match_data points to a match_data block
+ mcontext points to a match context
+ jit_stack points to a JIT stack
+
+Returns: > 0 => success; value is the number of ovector pairs filled
+ = 0 => success, but ovector is not big enough
+ -1 => failed to match (PCRE_ERROR_NOMATCH)
+ < -1 => some kind of unexpected problem
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
+ PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
+ pcre2_match_context *mcontext)
+{
+#ifndef SUPPORT_JIT
+
+(void)code;
+(void)subject;
+(void)length;
+(void)start_offset;
+(void)options;
+(void)match_data;
+(void)mcontext;
+return PCRE2_ERROR_JIT_BADOPTION;
+
+#else /* SUPPORT_JIT */
+
+pcre2_real_code *re = (pcre2_real_code *)code;
+executable_functions *functions = (executable_functions *)re->executable_jit;
+pcre2_jit_stack *jit_stack;
+uint32_t oveccount = match_data->oveccount;
+uint32_t max_oveccount;
+union {
+ void *executable_func;
+ jit_function call_executable_func;
+} convert_executable_func;
+jit_arguments arguments;
+int rc;
+int index = 0;
+
+if ((options & PCRE2_PARTIAL_HARD) != 0)
+ index = 2;
+else if ((options & PCRE2_PARTIAL_SOFT) != 0)
+ index = 1;
+
+if (functions->executable_funcs[index] == NULL)
+ return PCRE2_ERROR_JIT_BADOPTION;
+
+/* Sanity checks should be handled by pcre_exec. */
+arguments.str = subject + start_offset;
+arguments.begin = subject;
+arguments.end = subject + length;
+arguments.match_data = match_data;
+arguments.startchar_ptr = subject;
+arguments.mark_ptr = NULL;
+arguments.options = options;
+
+if (mcontext != NULL)
+ {
+ arguments.callout = mcontext->callout;
+ arguments.callout_data = mcontext->callout_data;
+ arguments.offset_limit = mcontext->offset_limit;
+ arguments.limit_match = (mcontext->match_limit < re->limit_match)?
+ mcontext->match_limit : re->limit_match;
+ if (mcontext->jit_callback != NULL)
+ jit_stack = mcontext->jit_callback(mcontext->jit_callback_data);
+ else
+ jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data;
+ }
+else
+ {
+ arguments.callout = NULL;
+ arguments.callout_data = NULL;
+ arguments.offset_limit = PCRE2_UNSET;
+ arguments.limit_match = (MATCH_LIMIT < re->limit_match)?
+ MATCH_LIMIT : re->limit_match;
+ jit_stack = NULL;
+ }
+
+/* JIT only need two offsets for each ovector entry. Hence
+ the last 1/3 of the ovector will never be touched. */
+
+max_oveccount = functions->top_bracket;
+if (oveccount > max_oveccount)
+ oveccount = max_oveccount;
+arguments.oveccount = oveccount << 1;
+
+
+convert_executable_func.executable_func = functions->executable_funcs[index];
+if (jit_stack != NULL)
+ {
+ arguments.stack = (struct sljit_stack *)(jit_stack->stack);
+ rc = convert_executable_func.call_executable_func(&arguments);
+ }
+else
+ rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func);
+
+if (rc > (int)oveccount)
+ rc = 0;
+match_data->code = re;
+match_data->subject = subject;
+match_data->rc = rc;
+match_data->startchar = arguments.startchar_ptr - subject;
+match_data->leftchar = 0;
+match_data->rightchar = 0;
+match_data->mark = arguments.mark_ptr;
+match_data->matchedby = PCRE2_MATCHEDBY_JIT;
+
+return match_data->rc;
+
+#endif /* SUPPORT_JIT */
+}
+
+/* End of pcre2_jit_match.c */
diff --git a/thirdparty/pcre2/src/pcre2_jit_misc.c b/thirdparty/pcre2/src/pcre2_jit_misc.c
new file mode 100644
index 0000000000..efdb05580f
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_jit_misc.c
@@ -0,0 +1,227 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
+#error This file must be included from pcre2_jit_compile.c.
+#endif
+
+
+
+/*************************************************
+* Free JIT read-only data *
+*************************************************/
+
+void
+PRIV(jit_free_rodata)(void *current, void *allocator_data)
+{
+#ifndef SUPPORT_JIT
+(void)current;
+(void)allocator_data;
+#else /* SUPPORT_JIT */
+void *next;
+
+SLJIT_UNUSED_ARG(allocator_data);
+
+while (current != NULL)
+ {
+ next = *(void**)current;
+ SLJIT_FREE(current, allocator_data);
+ current = next;
+ }
+
+#endif /* SUPPORT_JIT */
+}
+
+/*************************************************
+* Free JIT compiled code *
+*************************************************/
+
+void
+PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl)
+{
+#ifndef SUPPORT_JIT
+(void)executable_jit;
+(void)memctl;
+#else /* SUPPORT_JIT */
+
+executable_functions *functions = (executable_functions *)executable_jit;
+void *allocator_data = memctl;
+int i;
+
+for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
+ {
+ if (functions->executable_funcs[i] != NULL)
+ sljit_free_code(functions->executable_funcs[i]);
+ PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);
+ }
+
+SLJIT_FREE(functions, allocator_data);
+
+#endif /* SUPPORT_JIT */
+}
+
+
+/*************************************************
+* Free unused JIT memory *
+*************************************************/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_jit_free_unused_memory(pcre2_general_context *gcontext)
+{
+#ifndef SUPPORT_JIT
+(void)gcontext; /* Suppress warning */
+#else /* SUPPORT_JIT */
+SLJIT_UNUSED_ARG(gcontext);
+sljit_free_unused_memory_exec();
+#endif /* SUPPORT_JIT */
+}
+
+
+
+/*************************************************
+* Allocate a JIT stack *
+*************************************************/
+
+PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION
+pcre2_jit_stack_create(size_t startsize, size_t maxsize,
+ pcre2_general_context *gcontext)
+{
+#ifndef SUPPORT_JIT
+
+(void)gcontext;
+(void)startsize;
+(void)maxsize;
+return NULL;
+
+#else /* SUPPORT_JIT */
+
+pcre2_jit_stack *jit_stack;
+
+if (startsize < 1 || maxsize < 1)
+ return NULL;
+if (startsize > maxsize)
+ startsize = maxsize;
+startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+
+jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);
+if (jit_stack == NULL) return NULL;
+jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);
+return jit_stack;
+
+#endif
+}
+
+
+/*************************************************
+* Assign a JIT stack to a pattern *
+*************************************************/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback,
+ void *callback_data)
+{
+#ifndef SUPPORT_JIT
+(void)mcontext;
+(void)callback;
+(void)callback_data;
+#else /* SUPPORT_JIT */
+
+if (mcontext == NULL) return;
+mcontext->jit_callback = callback;
+mcontext->jit_callback_data = callback_data;
+
+#endif /* SUPPORT_JIT */
+}
+
+
+/*************************************************
+* Free a JIT stack *
+*************************************************/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_jit_stack_free(pcre2_jit_stack *jit_stack)
+{
+#ifndef SUPPORT_JIT
+(void)jit_stack;
+#else /* SUPPORT_JIT */
+if (jit_stack != NULL)
+ {
+ sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl);
+ jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
+ }
+#endif /* SUPPORT_JIT */
+}
+
+
+/*************************************************
+* Get target CPU type *
+*************************************************/
+
+const char*
+PRIV(jit_get_target)(void)
+{
+#ifndef SUPPORT_JIT
+return "JIT is not supported";
+#else /* SUPPORT_JIT */
+return sljit_get_platform_name();
+#endif /* SUPPORT_JIT */
+}
+
+
+/*************************************************
+* Get size of JIT code *
+*************************************************/
+
+size_t
+PRIV(jit_get_size)(void *executable_jit)
+{
+#ifndef SUPPORT_JIT
+(void)executable_jit;
+return 0;
+#else /* SUPPORT_JIT */
+sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes;
+SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed);
+return executable_sizes[0] + executable_sizes[1] + executable_sizes[2];
+#endif
+}
+
+/* End of pcre2_jit_misc.c */
diff --git a/thirdparty/pcre2/src/pcre2_jit_test.c b/thirdparty/pcre2/src/pcre2_jit_test.c
new file mode 100644
index 0000000000..705ba181eb
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_jit_test.c
@@ -0,0 +1,1735 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#define PCRE2_CODE_UNIT_WIDTH 0
+#include "pcre2.h"
+
+/*
+ Letter characters:
+ \xe6\x92\xad = 0x64ad = 25773 (kanji)
+ Non-letter characters:
+ \xc2\xa1 = 0xa1 = (Inverted Exclamation Mark)
+ \xf3\xa9\xb7\x80 = 0xe9dc0 = 957888
+ \xed\xa0\x80 = 55296 = 0xd800 (Invalid UTF character)
+ \xed\xb0\x80 = 56320 = 0xdc00 (Invalid UTF character)
+ Newlines:
+ \xc2\x85 = 0x85 = 133 (NExt Line = NEL)
+ \xe2\x80\xa8 = 0x2028 = 8232 (Line Separator)
+ Othercase pairs:
+ \xc3\xa9 = 0xe9 = 233 (e')
+ \xc3\x89 = 0xc9 = 201 (E')
+ \xc3\xa1 = 0xe1 = 225 (a')
+ \xc3\x81 = 0xc1 = 193 (A')
+ \x53 = 0x53 = S
+ \x73 = 0x73 = s
+ \xc5\xbf = 0x17f = 383 (long S)
+ \xc8\xba = 0x23a = 570
+ \xe2\xb1\xa5 = 0x2c65 = 11365
+ \xe1\xbd\xb8 = 0x1f78 = 8056
+ \xe1\xbf\xb8 = 0x1ff8 = 8184
+ \xf0\x90\x90\x80 = 0x10400 = 66560
+ \xf0\x90\x90\xa8 = 0x10428 = 66600
+ \xc7\x84 = 0x1c4 = 452
+ \xc7\x85 = 0x1c5 = 453
+ \xc7\x86 = 0x1c6 = 454
+ Caseless sets:
+ ucp_Armenian - \x{531}-\x{556} -> \x{561}-\x{586}
+ ucp_Coptic - \x{2c80}-\x{2ce3} -> caseless: XOR 0x1
+ ucp_Latin - \x{ff21}-\x{ff3a} -> \x{ff41]-\x{ff5a}
+
+ Mark property:
+ \xcc\x8d = 0x30d = 781
+ Special:
+ \xc2\x80 = 0x80 = 128 (lowest 2 byte character)
+ \xdf\xbf = 0x7ff = 2047 (highest 2 byte character)
+ \xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character)
+ \xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character)
+ \xf0\x90\x80\x80 = 0x10000 = 65536 (lowest 4 byte character)
+ \xf4\x8f\xbf\xbf = 0x10ffff = 1114111 (highest allowed utf character)
+*/
+
+static int regression_tests(void);
+
+int main(void)
+{
+ int jit = 0;
+#if defined SUPPORT_PCRE2_8
+ pcre2_config_8(PCRE2_CONFIG_JIT, &jit);
+#elif defined SUPPORT_PCRE2_16
+ pcre2_config_16(PCRE2_CONFIG_JIT, &jit);
+#elif defined SUPPORT_PCRE2_32
+ pcre2_config_32(PCRE2_CONFIG_JIT, &jit);
+#endif
+ if (!jit) {
+ printf("JIT must be enabled to run pcre_jit_test\n");
+ return 1;
+ }
+ return regression_tests();
+}
+
+/* --------------------------------------------------------------------------------------- */
+
+#if !(defined SUPPORT_PCRE2_8) && !(defined SUPPORT_PCRE2_16) && !(defined SUPPORT_PCRE2_32)
+#error SUPPORT_PCRE2_8 or SUPPORT_PCRE2_16 or SUPPORT_PCRE2_32 must be defined
+#endif
+
+#define MU (PCRE2_MULTILINE | PCRE2_UTF)
+#define MUP (PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP)
+#define CMU (PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF)
+#define CMUP (PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP)
+#define M (PCRE2_MULTILINE)
+#define MP (PCRE2_MULTILINE | PCRE2_UCP)
+#define U (PCRE2_UTF)
+#define CM (PCRE2_CASELESS | PCRE2_MULTILINE)
+
+#define BSR(x) ((x) << 16)
+#define A PCRE2_NEWLINE_ANYCRLF
+
+#define GET_NEWLINE(x) ((x) & 0xffff)
+#define GET_BSR(x) ((x) >> 16)
+
+#define OFFSET_MASK 0x00ffff
+#define F_NO8 0x010000
+#define F_NO16 0x020000
+#define F_NO32 0x020000
+#define F_NOMATCH 0x040000
+#define F_DIFF 0x080000
+#define F_FORCECONV 0x100000
+#define F_PROPERTY 0x200000
+
+struct regression_test_case {
+ int compile_options;
+ int newline;
+ int match_options;
+ int start_offset;
+ const char *pattern;
+ const char *input;
+};
+
+static struct regression_test_case regression_test_cases[] = {
+ /* Constant strings. */
+ { MU, A, 0, 0, "AbC", "AbAbC" },
+ { MU, A, 0, 0, "ACCEPT", "AACACCACCEACCEPACCEPTACCEPTT" },
+ { CMU, A, 0, 0, "aA#\xc3\xa9\xc3\x81", "aA#Aa#\xc3\x89\xc3\xa1" },
+ { M, A, 0, 0, "[^a]", "aAbB" },
+ { CM, A, 0, 0, "[^m]", "mMnN" },
+ { M, A, 0, 0, "a[^b][^#]", "abacd" },
+ { CM, A, 0, 0, "A[^B][^E]", "abacd" },
+ { CMU, A, 0, 0, "[^x][^#]", "XxBll" },
+ { MU, A, 0, 0, "[^a]", "aaa\xc3\xa1#Ab" },
+ { CMU, A, 0, 0, "[^A]", "aA\xe6\x92\xad" },
+ { MU, A, 0, 0, "\\W(\\W)?\\w", "\r\n+bc" },
+ { MU, A, 0, 0, "\\W(\\W)?\\w", "\n\r+bc" },
+ { MU, A, 0, 0, "\\W(\\W)?\\w", "\r\r+bc" },
+ { MU, A, 0, 0, "\\W(\\W)?\\w", "\n\n+bc" },
+ { MU, A, 0, 0, "[axd]", "sAXd" },
+ { CMU, A, 0, 0, "[axd]", "sAXd" },
+ { CMU, A, 0, 0 | F_NOMATCH, "[^axd]", "DxA" },
+ { MU, A, 0, 0, "[a-dA-C]", "\xe6\x92\xad\xc3\xa9.B" },
+ { MU, A, 0, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" },
+ { CMU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." },
+ { MU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." },
+ { MU, A, 0, 0, "[^a]", "\xc2\x80[]" },
+ { CMU, A, 0, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" },
+ { CM, A, 0, 0, "1a2b3c4", "1a2B3c51A2B3C4" },
+ { PCRE2_CASELESS, 0, 0, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" },
+ { PCRE2_CASELESS, 0, 0, 0, "\xfe", "\xff\xfc#\xfe\xfe" },
+ { PCRE2_CASELESS, 0, 0, 0, "a1", "Aa1" },
+ { M, A, 0, 0, "\\Ca", "cda" },
+ { CM, A, 0, 0, "\\Ca", "CDA" },
+ { M, A, 0, 0 | F_NOMATCH, "\\Cx", "cda" },
+ { CM, A, 0, 0 | F_NOMATCH, "\\Cx", "CDA" },
+ { CMUP, A, 0, 0, "\xf0\x90\x90\x80\xf0\x90\x90\xa8", "\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
+ { CMUP, A, 0, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
+ { CMUP, A, 0, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
+ { CMUP, A, 0, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" },
+ { M, A, 0, 0, "[3-57-9]", "5" },
+
+ /* Assertions. */
+ { MU, A, 0, 0, "\\b[^A]", "A_B#" },
+ { M, A, 0, 0 | F_NOMATCH, "\\b\\W", "\n*" },
+ { MU, A, 0, 0, "\\B[^,]\\b[^s]\\b", "#X" },
+ { MP, A, 0, 0, "\\B", "_\xa1" },
+ { MP, A, 0, 0 | F_PROPERTY, "\\b_\\b[,A]\\B", "_," },
+ { MUP, A, 0, 0, "\\b", "\xe6\x92\xad!" },
+ { MUP, A, 0, 0, "\\B", "_\xc2\xa1\xc3\xa1\xc2\x85" },
+ { MUP, A, 0, 0, "\\b[^A]\\B[^c]\\b[^_]\\B", "_\xc3\xa1\xe2\x80\xa8" },
+ { MUP, A, 0, 0, "\\b\\w+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" },
+ { MU, A, 0, 0 | F_NOMATCH, "\\b.", "\xcd\xbe" },
+ { CMUP, A, 0, 0, "\\By", "\xf0\x90\x90\xa8y" },
+ { M, A, 0, 0 | F_NOMATCH, "\\R^", "\n" },
+ { M, A, 0, 1 | F_NOMATCH, "^", "\n" },
+ { 0, 0, 0, 0, "^ab", "ab" },
+ { 0, 0, 0, 0 | F_NOMATCH, "^ab", "aab" },
+ { M, PCRE2_NEWLINE_CRLF, 0, 0, "^a", "\r\raa\n\naa\r\naa" },
+ { MU, A, 0, 0, "^-", "\xe2\x80\xa8--\xc2\x85-\r\n-" },
+ { M, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--b--\x85--" },
+ { MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xe2\x80\xa8--" },
+ { MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xc2\x85--" },
+ { 0, 0, 0, 0, "ab$", "ab" },
+ { 0, 0, 0, 0 | F_NOMATCH, "ab$", "abab\n\n" },
+ { PCRE2_DOLLAR_ENDONLY, 0, 0, 0 | F_NOMATCH, "ab$", "abab\r\n" },
+ { M, PCRE2_NEWLINE_CRLF, 0, 0, "a$", "\r\raa\n\naa\r\naa" },
+ { M, PCRE2_NEWLINE_ANY, 0, 0, "a$", "aaa" },
+ { MU, PCRE2_NEWLINE_ANYCRLF, 0, 0, "#$", "#\xc2\x85###\r#" },
+ { MU, PCRE2_NEWLINE_ANY, 0, 0, "#$", "#\xe2\x80\xa9" },
+ { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0 | F_NOMATCH, "^a", "aa\naa" },
+ { M, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0, "^a", "aa\naa" },
+ { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\naa" },
+ { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\r\n" },
+ { U | PCRE2_DOLLAR_ENDONLY, PCRE2_NEWLINE_ANY, 0, 0 | F_PROPERTY, "\\p{Any}{2,}$", "aa\r\n" },
+ { M, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0, "a$", "aa\naa" },
+ { 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa" },
+ { U, PCRE2_NEWLINE_CR, 0, 0, "a\\Z", "aaa\r" },
+ { 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa\n" },
+ { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r" },
+ { U, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\n" },
+ { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r\n" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" },
+ { U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xc2\x85" },
+ { U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" },
+ { M, A, 0, 0, "\\Aa", "aaa" },
+ { M, A, 0, 1 | F_NOMATCH, "\\Aa", "aaa" },
+ { M, A, 0, 1, "\\Ga", "aaa" },
+ { M, A, 0, 1 | F_NOMATCH, "\\Ga", "aba" },
+ { M, A, 0, 0, "a\\z", "aaa" },
+ { M, A, 0, 0 | F_NOMATCH, "a\\z", "aab" },
+
+ /* Brackets and alternatives. */
+ { MU, A, 0, 0, "(ab|bb|cd)", "bacde" },
+ { MU, A, 0, 0, "(?:ab|a)(bc|c)", "ababc" },
+ { MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" },
+ { CMU, A, 0, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" },
+ { MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" },
+ { MU, A, 0, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" },
+ { MU, A, 0, 0, "\xc7\x82|\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" },
+ { MU, A, 0, 0, "=\xc7\x82|#\xc6\x82", "\xf1\x83\x82\x82=\xc7\x82\xc7\x83" },
+ { MU, A, 0, 0, "\xc7\x82\xc7\x83|\xc6\x82\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" },
+ { MU, A, 0, 0, "\xc6\x82\xc6\x82|\xc7\x83\xc7\x83|\xc8\x84\xc8\x84", "\xf1\x83\x82\x82\xc8\x84\xc8\x84" },
+
+ /* Greedy and non-greedy ? operators. */
+ { MU, A, 0, 0, "(?:a)?a", "laab" },
+ { CMU, A, 0, 0, "(A)?A", "llaab" },
+ { MU, A, 0, 0, "(a)?\?a", "aab" }, /* ?? is the prefix of trygraphs in GCC. */
+ { MU, A, 0, 0, "(a)?a", "manm" },
+ { CMU, A, 0, 0, "(a|b)?\?d((?:e)?)", "ABABdx" },
+ { MU, A, 0, 0, "(a|b)?\?d((?:e)?)", "abcde" },
+ { MU, A, 0, 0, "((?:ab)?\?g|b(?:g(nn|d)?\?)?)?\?(?:n)?m", "abgnbgnnbgdnmm" },
+
+ /* Greedy and non-greedy + operators */
+ { MU, A, 0, 0, "(aa)+aa", "aaaaaaa" },
+ { MU, A, 0, 0, "(aa)+?aa", "aaaaaaa" },
+ { MU, A, 0, 0, "(?:aba|ab|a)+l", "ababamababal" },
+ { MU, A, 0, 0, "(?:aba|ab|a)+?l", "ababamababal" },
+ { MU, A, 0, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },
+ { MU, A, 0, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },
+ { MU, A, 0, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" },
+
+ /* Greedy and non-greedy * operators */
+ { CMU, A, 0, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" },
+ { MU, A, 0, 0, "(?:aa)*?ab", "aaaaaaamaaaaaaab" },
+ { MU, A, 0, 0, "(aa|ab)*ab", "aaabaaab" },
+ { CMU, A, 0, 0, "(aa|Ab)*?aB", "aaabaaab" },
+ { MU, A, 0, 0, "(a|b)*(?:a)*(?:b)*m", "abbbaaababanabbbaaababamm" },
+ { MU, A, 0, 0, "(a|b)*?(?:a)*?(?:b)*?m", "abbbaaababanabbbaaababamm" },
+ { M, A, 0, 0, "a(a(\\1*)a|(b)b+){0}a", "aa" },
+ { M, A, 0, 0, "((?:a|)*){0}a", "a" },
+
+ /* Combining ? + * operators */
+ { MU, A, 0, 0, "((bm)+)?\?(?:a)*(bm)+n|((am)+?)?(?:a)+(am)*n", "bmbmabmamaaamambmaman" },
+ { MU, A, 0, 0, "(((ab)?cd)*ef)+g", "abcdcdefcdefefmabcdcdefcdefefgg" },
+ { MU, A, 0, 0, "(((ab)?\?cd)*?ef)+?g", "abcdcdefcdefefmabcdcdefcdefefgg" },
+ { MU, A, 0, 0, "(?:(ab)?c|(?:ab)+?d)*g", "ababcdccababddg" },
+ { MU, A, 0, 0, "(?:(?:ab)?\?c|(ab)+d)*?g", "ababcdccababddg" },
+
+ /* Single character iterators. */
+ { MU, A, 0, 0, "(a+aab)+aaaab", "aaaabcaaaabaabcaabcaaabaaaab" },
+ { MU, A, 0, 0, "(a*a*aab)+x", "aaaaabaabaaabmaabx" },
+ { MU, A, 0, 0, "(a*?(b|ab)a*?)+x", "aaaabcxbbaabaacbaaabaabax" },
+ { MU, A, 0, 0, "(a+(ab|ad)a+)+x", "aaabaaaadaabaaabaaaadaaax" },
+ { MU, A, 0, 0, "(a?(a)a?)+(aaa)", "abaaabaaaaaaaa" },
+ { MU, A, 0, 0, "(a?\?(a)a?\?)+(b)", "aaaacaaacaacacbaaab" },
+ { MU, A, 0, 0, "(a{0,4}(b))+d", "aaaaaabaabcaaaaabaaaaabd" },
+ { MU, A, 0, 0, "(a{0,4}?[^b])+d+(a{0,4}[^b])d+", "aaaaadaaaacaadddaaddd" },
+ { MU, A, 0, 0, "(ba{2})+c", "baabaaabacbaabaac" },
+ { MU, A, 0, 0, "(a*+bc++)+", "aaabbcaaabcccab" },
+ { MU, A, 0, 0, "(a?+[^b])+", "babaacacb" },
+ { MU, A, 0, 0, "(a{0,3}+b)(a{0,3}+b)(a{0,3}+)[^c]", "abaabaaacbaabaaaac" },
+ { CMU, A, 0, 0, "([a-c]+[d-f]+?)+?g", "aBdacdehAbDaFgA" },
+ { CMU, A, 0, 0, "[c-f]+k", "DemmFke" },
+ { MU, A, 0, 0, "([DGH]{0,4}M)+", "GGDGHDGMMHMDHHGHM" },
+ { MU, A, 0, 0, "([a-c]{4,}s)+", "abasabbasbbaabsbba" },
+ { CMU, A, 0, 0, "[ace]{3,7}", "AcbDAcEEcEd" },
+ { CMU, A, 0, 0, "[ace]{3,7}?", "AcbDAcEEcEd" },
+ { CMU, A, 0, 0, "[ace]{3,}", "AcbDAcEEcEd" },
+ { CMU, A, 0, 0, "[ace]{3,}?", "AcbDAcEEcEd" },
+ { MU, A, 0, 0, "[ckl]{2,}?g", "cdkkmlglglkcg" },
+ { CMU, A, 0, 0, "[ace]{5}?", "AcCebDAcEEcEd" },
+ { MU, A, 0, 0, "([AbC]{3,5}?d)+", "BACaAbbAEAACCbdCCbdCCAAbb" },
+ { MU, A, 0, 0, "([^ab]{0,}s){2}", "abaabcdsABamsDDs" },
+ { MU, A, 0, 0, "\\b\\w+\\B", "x,a_cd" },
+ { MUP, A, 0, 0, "\\b[^\xc2\xa1]+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" },
+ { CMU, A, 0, 0, "[^b]+(a*)([^c]?d{3})", "aaaaddd" },
+ { CMUP, A, 0, 0, "\xe1\xbd\xb8{2}", "\xe1\xbf\xb8#\xe1\xbf\xb8\xe1\xbd\xb8" },
+ { CMU, A, 0, 0, "[^\xf0\x90\x90\x80]{2,4}@", "\xf0\x90\x90\xa8\xf0\x90\x90\x80###\xf0\x90\x90\x80@@@" },
+ { CMU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" },
+ { MU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" },
+ { MU, A, 0, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" },
+ { MU, A, 0, 0, "\\d+123", "987654321,01234" },
+ { MU, A, 0, 0, "abcd*|\\w+xy", "aaaaa,abxyz" },
+ { MU, A, 0, 0, "(?:abc|((?:amc|\\b\\w*xy)))", "aaaaa,abxyz" },
+ { MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.abcd#."},
+ { MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.mbcd#."},
+ { MU, A, 0, 0, ".[ab]*.", "xx" },
+ { MU, A, 0, 0, ".[ab]*a", "xxa" },
+ { MU, A, 0, 0, ".[ab]?.", "xx" },
+
+ /* Bracket repeats with limit. */
+ { MU, A, 0, 0, "(?:(ab){2}){5}M", "abababababababababababM" },
+ { MU, A, 0, 0, "(?:ab|abab){1,5}M", "abababababababababababM" },
+ { MU, A, 0, 0, "(?>ab|abab){1,5}M", "abababababababababababM" },
+ { MU, A, 0, 0, "(?:ab|abab){1,5}?M", "abababababababababababM" },
+ { MU, A, 0, 0, "(?>ab|abab){1,5}?M", "abababababababababababM" },
+ { MU, A, 0, 0, "(?:(ab){1,4}?){1,3}?M", "abababababababababababababM" },
+ { MU, A, 0, 0, "(?:(ab){1,4}){1,3}abababababababababababM", "ababababababababababababM" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?:(ab){1,4}){1,3}abababababababababababM", "abababababababababababM" },
+ { MU, A, 0, 0, "(ab){4,6}?M", "abababababababM" },
+
+ /* Basic character sets. */
+ { MU, A, 0, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " },
+ { MU, A, 0, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" },
+ { MU, A, 0, 0, "\\((\\d)+\\)\\D", "a() (83 (8)2 (9)ab" },
+ { MU, A, 0, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" },
+ { MU, A, 0, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" },
+ { MU, A, 0, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" },
+ { MU, A, 0, 0, "x[bcef]+", "xaxdxecbfg" },
+ { MU, A, 0, 0, "x[bcdghij]+", "xaxexfxdgbjk" },
+ { MU, A, 0, 0, "x[^befg]+", "xbxexacdhg" },
+ { MU, A, 0, 0, "x[^bcdl]+", "xlxbxaekmd" },
+ { MU, A, 0, 0, "x[^bcdghi]+", "xbxdxgxaefji" },
+ { MU, A, 0, 0, "x[B-Fb-f]+", "xaxAxgxbfBFG" },
+ { CMU, A, 0, 0, "\\x{e9}+", "#\xf0\x90\x90\xa8\xc3\xa8\xc3\xa9\xc3\x89\xc3\x88" },
+ { CMU, A, 0, 0, "[^\\x{e9}]+", "\xc3\xa9#\xf0\x90\x90\xa8\xc3\xa8\xc3\x88\xc3\x89" },
+ { MU, A, 0, 0, "[\\x02\\x7e]+", "\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x02\x7e\x7f" },
+ { MU, A, 0, 0, "[^\\x02\\x7e]+", "\x02\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x7f\x7e" },
+ { MU, A, 0, 0, "[\\x{81}-\\x{7fe}]+", "#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xc2\x81\xdf\xbe\xdf\xbf" },
+ { MU, A, 0, 0, "[^\\x{81}-\\x{7fe}]+", "\xc2\x81#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xdf\xbf\xdf\xbe" },
+ { MU, A, 0, 0, "[\\x{801}-\\x{fffe}]+", "#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xe0\xa0\x81\xef\xbf\xbe\xef\xbf\xbf" },
+ { MU, A, 0, 0, "[^\\x{801}-\\x{fffe}]+", "\xe0\xa0\x81#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xef\xbf\xbf\xef\xbf\xbe" },
+ { MU, A, 0, 0, "[\\x{10001}-\\x{10fffe}]+", "#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf0\x90\x80\x81\xf4\x8f\xbf\xbe\xf4\x8f\xbf\xbf" },
+ { MU, A, 0, 0, "[^\\x{10001}-\\x{10fffe}]+", "\xf0\x90\x80\x81#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbe" },
+
+ /* Unicode properties. */
+ { MUP, A, 0, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" },
+ { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\x81\\p{Ll}]", "A_\xc3\x89\xc3\xa1" },
+ { MUP, A, 0, 0, "[\\Wd-h_x-z]+", "a\xc2\xa1#_yhzdxi" },
+ { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}]", "abc" },
+ { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}]", "abc" },
+ { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}\xc3\xa1-\xc3\xa8]", "abc" },
+ { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}\xc3\xa1-\xc3\xa8]", "abc" },
+ { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" },
+ { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" },
+ { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" },
+ { MUP, A, 0, 0 | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" },
+ { MUP, A, 0, 0, "[b-\xc3\xa9\\s]", "a\xc\xe6\x92\xad" },
+ { CMUP, A, 0, 0, "[\xc2\x85-\xc2\x89\xc3\x89]", "\xc2\x84\xc3\xa9" },
+ { MUP, A, 0, 0, "[^b-d^&\\s]{3,}", "db^ !a\xe2\x80\xa8_ae" },
+ { MUP, A, 0, 0 | F_PROPERTY, "[^\\S\\P{Any}][\\sN]{1,3}[\\P{N}]{4}", "\xe2\x80\xaa\xa N\x9\xc3\xa9_0" },
+ { MU, A, 0, 0 | F_PROPERTY, "[^\\P{L}\x9!D-F\xa]{2,3}", "\x9,.DF\xa.CG\xc3\x81" },
+ { CMUP, A, 0, 0, "[\xc3\xa1-\xc3\xa9_\xe2\x80\xa0-\xe2\x80\xaf]{1,5}[^\xe2\x80\xa0-\xe2\x80\xaf]", "\xc2\xa1\xc3\x89\xc3\x89\xe2\x80\xaf_\xe2\x80\xa0" },
+ { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" },
+ { MUP, A, 0, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" },
+ { PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "[a-b\\s]{2,5}[^a]", "AB baaa" },
+
+ /* Possible empty brackets. */
+ { MU, A, 0, 0, "(?:|ab||bc|a)+d", "abcxabcabd" },
+ { MU, A, 0, 0, "(|ab||bc|a)+d", "abcxabcabd" },
+ { MU, A, 0, 0, "(?:|ab||bc|a)*d", "abcxabcabd" },
+ { MU, A, 0, 0, "(|ab||bc|a)*d", "abcxabcabd" },
+ { MU, A, 0, 0, "(?:|ab||bc|a)+?d", "abcxabcabd" },
+ { MU, A, 0, 0, "(|ab||bc|a)+?d", "abcxabcabd" },
+ { MU, A, 0, 0, "(?:|ab||bc|a)*?d", "abcxabcabd" },
+ { MU, A, 0, 0, "(|ab||bc|a)*?d", "abcxabcabd" },
+ { MU, A, 0, 0, "(((a)*?|(?:ba)+)+?|(?:|c|ca)*)*m", "abaacaccabacabalabaacaccabacabamm" },
+ { MU, A, 0, 0, "(?:((?:a)*|(ba)+?)+|(|c|ca)*?)*?m", "abaacaccabacabalabaacaccabacabamm" },
+
+ /* Start offset. */
+ { MU, A, 0, 3, "(\\d|(?:\\w)*\\w)+", "0ac01Hb" },
+ { MU, A, 0, 4 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" },
+ { MU, A, 0, 2 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" },
+ { MU, A, 0, 1, "(\\w\\W\\w)+", "ab#d" },
+
+ /* Newline. */
+ { M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },
+ { M, PCRE2_NEWLINE_CR, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },
+ { M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{1,3}[^#]", "\r\n##...." },
+ { MU, A, PCRE2_NO_UTF_CHECK, 1, "^.a", "\n\x80\nxa" },
+ { MU, A, 0, 1, "^", "\r\n" },
+ { M, PCRE2_NEWLINE_CRLF, 0, 1 | F_NOMATCH, "^", "\r\n" },
+ { M, PCRE2_NEWLINE_CRLF, 0, 1, "^", "\r\na" },
+
+ /* Any character except newline or any newline. */
+ { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" },
+ { U, PCRE2_NEWLINE_CRLF, 0, 0, ".(.).", "a\xc3\xa1\r\n\n\r\r" },
+ { 0, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" },
+ { U, PCRE2_NEWLINE_ANY, 0, 0, "(.).", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa9$de" },
+ { U, PCRE2_NEWLINE_ANYCRLF, 0, 0 | F_NOMATCH, ".(.).", "\xe2\x80\xa8\nb\r" },
+ { 0, PCRE2_NEWLINE_ANY, 0, 0, "(.)(.)", "#\x85#\r#\n#\r\n#\x84" },
+ { U, PCRE2_NEWLINE_ANY, 0, 0, "(.+)#", "#\rMn\xc2\x85#\n###" },
+ { 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\r" },
+ { 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\x85#\r\n#" },
+ { U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\xe2\x80\xa8#c" },
+ { U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\r\nc" },
+ { U, PCRE2_NEWLINE_CRLF | BSR(PCRE2_BSR_UNICODE), 0, 0, "(\\R.)+", "\xc2\x85\r\n#\xe2\x80\xa8\n\r\n\r" },
+ { MU, A, 0, 0 | F_NOMATCH, "\\R+", "ab" },
+ { MU, A, 0, 0, "\\R+", "ab\r\n\r" },
+ { MU, A, 0, 0, "\\R*", "ab\r\n\r" },
+ { MU, A, 0, 0, "\\R*", "\r\n\r" },
+ { MU, A, 0, 0, "\\R{2,4}", "\r\nab\r\r" },
+ { MU, A, 0, 0, "\\R{2,4}", "\r\nab\n\n\n\r\r\r" },
+ { MU, A, 0, 0, "\\R{2,}", "\r\nab\n\n\n\r\r\r" },
+ { MU, A, 0, 0, "\\R{0,3}", "\r\n\r\n\r\n\r\n\r\n" },
+ { MU, A, 0, 0 | F_NOMATCH, "\\R+\\R\\R", "\r\n\r\n" },
+ { MU, A, 0, 0, "\\R+\\R\\R", "\r\r\r" },
+ { MU, A, 0, 0, "\\R*\\R\\R", "\n\r" },
+ { MU, A, 0, 0 | F_NOMATCH, "\\R{2,4}\\R\\R", "\r\r\r" },
+ { MU, A, 0, 0, "\\R{2,4}\\R\\R", "\r\r\r\r" },
+
+ /* Atomic groups (no fallback from "next" direction). */
+ { MU, A, 0, 0 | F_NOMATCH, "(?>ab)ab", "bab" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?>(ab))ab", "bab" },
+ { MU, A, 0, 0, "(?>ab)+abc(?>de)*def(?>gh)?ghe(?>ij)+?k(?>lm)*?n(?>op)?\?op",
+ "bababcdedefgheijijklmlmnop" },
+ { MU, A, 0, 0, "(?>a(b)+a|(ab)?\?(b))an", "abban" },
+ { MU, A, 0, 0, "(?>ab+a|(?:ab)?\?b)an", "abban" },
+ { MU, A, 0, 0, "((?>ab|ad|)*?)(?>|c)*abad", "abababcababad" },
+ { MU, A, 0, 0, "(?>(aa|b|)*+(?>(##)|###)*d|(aa)(?>(baa)?)m)", "aabaa#####da" },
+ { MU, A, 0, 0, "((?>a|)+?)b", "aaacaaab" },
+ { MU, A, 0, 0, "(?>x|)*$", "aaa" },
+ { MU, A, 0, 0, "(?>(x)|)*$", "aaa" },
+ { MU, A, 0, 0, "(?>x|())*$", "aaa" },
+ { MU, A, 0, 0, "((?>[cxy]a|[a-d])*?)b", "aaa+ aaab" },
+ { MU, A, 0, 0, "((?>[cxy](a)|[a-d])*?)b", "aaa+ aaab" },
+ { MU, A, 0, 0, "(?>((?>(a+))))bab|(?>((?>(a+))))bb", "aaaabaaabaabab" },
+ { MU, A, 0, 0, "(?>(?>a+))bab|(?>(?>a+))bb", "aaaabaaabaabab" },
+ { MU, A, 0, 0, "(?>(a)c|(?>(c)|(a))a)b*?bab", "aaaabaaabaabab" },
+ { MU, A, 0, 0, "(?>ac|(?>c|a)a)b*?bab", "aaaabaaabaabab" },
+ { MU, A, 0, 0, "(?>(b)b|(a))*b(?>(c)|d)?x", "ababcaaabdbx" },
+ { MU, A, 0, 0, "(?>bb|a)*b(?>c|d)?x", "ababcaaabdbx" },
+ { MU, A, 0, 0, "(?>(bb)|a)*b(?>c|(d))?x", "ababcaaabdbx" },
+ { MU, A, 0, 0, "(?>(a))*?(?>(a))+?(?>(a))??x", "aaaaaacccaaaaabax" },
+ { MU, A, 0, 0, "(?>a)*?(?>a)+?(?>a)??x", "aaaaaacccaaaaabax" },
+ { MU, A, 0, 0, "(?>(a)|)*?(?>(a)|)+?(?>(a)|)??x", "aaaaaacccaaaaabax" },
+ { MU, A, 0, 0, "(?>a|)*?(?>a|)+?(?>a|)??x", "aaaaaacccaaaaabax" },
+ { MU, A, 0, 0, "(?>a(?>(a{0,2}))*?b|aac)+b", "aaaaaaacaaaabaaaaacaaaabaacaaabb" },
+ { CM, A, 0, 0, "(?>((?>a{32}|b+|(a*))?(?>c+|d*)?\?)+e)+?f", "aaccebbdde bbdaaaccebbdee bbdaaaccebbdeef" },
+ { MU, A, 0, 0, "(?>(?:(?>aa|a||x)+?b|(?>aa|a||(x))+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" },
+ { MU, A, 0, 0, "(?>(?:(?>aa|a||(x))+?b|(?>aa|a||x)+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" },
+ { MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d" },
+ { MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d#\xcc\x8d\xcc\x8d" },
+ { MU, A, 0, 0 | F_PROPERTY, "\\X+..", "\xcc\x8d#\xcc\x8d#\xcc\x8d\xcc\x8d" },
+ { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}", "abcdef" },
+ { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}?", "abcdef" },
+ { MU, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d##" },
+ { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d#\xcc\x8d##" },
+ { MU, A, 0, 0, "(c(ab)?+ab)+", "cabcababcab" },
+ { MU, A, 0, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" },
+
+ /* Possessive quantifiers. */
+ { MU, A, 0, 0, "(?:a|b)++m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "(?:a|b)*+m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "(?:a|b)*+m", "ababbaaxababbaam" },
+ { MU, A, 0, 0, "(a|b)++m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "(a|b)*+m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "(a|b)*+m", "ababbaaxababbaam" },
+ { MU, A, 0, 0, "(a|b(*ACCEPT))++m", "maaxab" },
+ { MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0, "(b*)++m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "(b*)++m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0, "(?:a|(b))++m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" },
+ { MU, A, 0, 0, "(a|(b))++m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "((a)|b)*+m", "mababbaaxababbaam" },
+ { MU, A, 0, 0, "((a)|(b))*+m", "ababbaaxababbaam" },
+ { MU, A, 0, 0, "(a|(b)(*ACCEPT))++m", "maaxab" },
+ { MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0, "((b*))++m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "((b*))++m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxm" },
+ { MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxbbm" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?>(b{2,4}))(?:(?:(aa|c))++m|(?:(aa|c))+n)", "bbaacaaccaaaacxbbbmbn" },
+ { MU, A, 0, 0, "((?:b)++a)+(cd)*+m", "bbababbacdcdnbbababbacdcdm" },
+ { MU, A, 0, 0, "((?:(b))++a)+((c)d)*+m", "bbababbacdcdnbbababbacdcdm" },
+ { MU, A, 0, 0, "(?:(?:(?:ab)*+k)++(?:n(?:cd)++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" },
+ { MU, A, 0, 0, "(?:((ab)*+(k))++(n(?:c(d))++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" },
+
+ /* Back references. */
+ { MU, A, 0, 0, "(aa|bb)(\\1*)(ll|)(\\3*)bbbbbbc", "aaaaaabbbbbbbbc" },
+ { CMU, A, 0, 0, "(aa|bb)(\\1+)(ll|)(\\3+)bbbbbbc", "bBbbBbCbBbbbBbbcbbBbbbBBbbC" },
+ { CM, A, 0, 0, "(a{2,4})\\1", "AaAaaAaA" },
+ { MU, A, 0, 0, "(aa|bb)(\\1?)aa(\\1?)(ll|)(\\4+)bbc", "aaaaaaaabbaabbbbaabbbbc" },
+ { MU, A, 0, 0, "(aa|bb)(\\1{0,5})(ll|)(\\3{0,5})cc", "bbxxbbbbxxaaaaaaaaaaaaaaaacc" },
+ { MU, A, 0, 0, "(aa|bb)(\\1{3,5})(ll|)(\\3{3,5})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" },
+ { MU, A, 0, 0, "(aa|bb)(\\1{3,})(ll|)(\\3{3,})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" },
+ { MU, A, 0, 0, "(\\w+)b(\\1+)c", "GabGaGaDbGaDGaDc" },
+ { MU, A, 0, 0, "(?:(aa)|b)\\1?b", "bb" },
+ { CMU, A, 0, 0, "(aa|bb)(\\1*?)aa(\\1+?)", "bBBbaaAAaaAAaa" },
+ { MU, A, 0, 0, "(aa|bb)(\\1*?)(dd|)cc(\\3+?)", "aaaaaccdd" },
+ { CMU, A, 0, 0, "(?:(aa|bb)(\\1?\?)cc){2}(\\1?\?)", "aAaABBbbAAaAcCaAcCaA" },
+ { MU, A, 0, 0, "(?:(aa|bb)(\\1{3,5}?)){2}(dd|)(\\3{3,5}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" },
+ { CM, A, 0, 0, "(?:(aa|bb)(\\1{3,}?)){2}(dd|)(\\3{3,}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" },
+ { MU, A, 0, 0, "(?:(aa|bb)(\\1{0,3}?)){2}(dd|)(\\3{0,3}?)b(\\1{0,3}?)(\\1{0,3})", "aaaaaaaaaaaaaaabaaaaa" },
+ { MU, A, 0, 0, "(a(?:\\1|)a){3}b", "aaaaaaaaaaab" },
+ { M, A, 0, 0, "(a?)b(\\1\\1*\\1+\\1?\\1*?\\1+?\\1??\\1*+\\1++\\1?+\\1{4}\\1{3,5}\\1{4,}\\1{0,5}\\1{3,5}?\\1{4,}?\\1{0,5}?\\1{3,5}+\\1{4,}+\\1{0,5}+#){2}d", "bb#b##d" },
+ { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." },
+ { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{0,2}", "wwwww." },
+ { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwww" },
+ { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwwww" },
+ { PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." },
+ { CMUP, A, 0, 0, "(\xf0\x90\x90\x80)\\1", "\xf0\x90\x90\xa8\xf0\x90\x90\xa8" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k<A>{1,3}(?<A>aa)(?<A>bb)", "aabb" },
+ { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k<A>{1,3}(?<A>aa)(?<A>bb)", "aabb" },
+ { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k<A>*(?<A>aa)(?<A>bb)", "aabb" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0, "(?<A>aa)(?<A>bb)\\k<A>{0,3}aaaaaa", "aabbaaaaaa" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0, "(?<A>aa)(?<A>bb)\\k<A>{2,5}bb", "aabbaaaabb" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>{0,3}m", "aaaaaaaabbbbaabbbbm" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k<A>{1,3}?(?<A>aa)(?<A>bb)", "aabb" },
+ { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k<A>{1,3}?(?<A>aa)(?<A>bb)", "aabb" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0, "\\k<A>*?(?<A>aa)(?<A>bb)", "aabb" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>{0,3}?m", "aaaaaabbbbbbaabbbbbbbbbbm" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>*?m", "aaaaaabbbbbbaabbbbbbbbbbm" },
+ { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>{2,3}?", "aaaabbbbaaaabbbbbbbbbb" },
+ { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{0,3}M", "aaaaaaaabbbbaabbbbm" },
+ { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{1,3}M", "aaaaaaaabbbbaabbbbm" },
+ { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{0,3}?M", "aaaaaabbbbbbaabbbbbbbbbbm" },
+ { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{2,3}?", "aaaabbbbaaaabbbbbbbbbb" },
+
+ /* Assertions. */
+ { MU, A, 0, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" },
+ { MU, A, 0, 0, "(?=((\\w+)b){3}|ab)", "dbbbb ab" },
+ { MU, A, 0, 0, "(?!ab|bc|cd)[a-z]{2}", "Xabcdef" },
+ { MU, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" },
+ { MU, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" },
+ { M, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" },
+ { M, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" },
+ { MU, A, 0, 0, "(\\d{2})(?!\\w+c|(((\\w?)m){2}n)+|\\1)", "x5656" },
+ { MU, A, 0, 0, "((?=((\\d{2,6}\\w){2,}))\\w{5,20}K){2,}", "567v09708K12l00M00 567v09708K12l00M00K45K" },
+ { MU, A, 0, 0, "(?=(?:(?=\\S+a)\\w*(b)){3})\\w+\\d", "bba bbab nbbkba nbbkba0kl" },
+ { MU, A, 0, 0, "(?>a(?>(b+))a(?=(..)))*?k", "acabbcabbaabacabaabbakk" },
+ { MU, A, 0, 0, "((?(?=(a))a)+k)", "bbak" },
+ { MU, A, 0, 0, "((?(?=a)a)+k)", "bbak" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?=(?>(a))m)amk", "a k" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?!(?>(a))m)amk", "a k" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?>(?=(a))am)amk", "a k" },
+ { MU, A, 0, 0, "(?=(?>a|(?=(?>(b+))a|c)[a-c]+)*?m)[a-cm]+k", "aaam bbam baaambaam abbabba baaambaamk" },
+ { MU, A, 0, 0, "(?> ?\?\\b(?(?=\\w{1,4}(a))m)\\w{0,8}bc){2,}?", "bca ssbc mabd ssbc mabc" },
+ { MU, A, 0, 0, "(?:(?=ab)?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" },
+ { MU, A, 0, 0, "(?:(?=a(b))?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" },
+ { MU, A, 0, 0, "(?:(?=.(.))??\\1.)+m", "aabbbcbacccanaabbbcbacccam" },
+ { MU, A, 0, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" },
+ { MU, A, 0, 0, "((?!a)?(?!([^a]))?)+$", "acbab" },
+ { MU, A, 0, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" },
+ { MU, A, 0, 0, "a(?=(?C)\\B(?C`x`))b", "ab" },
+ { MU, A, 0, 0, "a(?!(?C)\\B(?C`x`))bb|ab", "abb" },
+ { MU, A, 0, 0, "a(?=\\b|(?C)\\B(?C`x`))b", "ab" },
+ { MU, A, 0, 0, "a(?!\\b|(?C)\\B(?C`x`))bb|ab", "abb" },
+ { MU, A, 0, 0, "c(?(?=(?C)\\B(?C`x`))ab|a)", "cab" },
+ { MU, A, 0, 0, "c(?(?!(?C)\\B(?C`x`))ab|a)", "cab" },
+ { MU, A, 0, 0, "c(?(?=\\b|(?C)\\B(?C`x`))ab|a)", "cab" },
+ { MU, A, 0, 0, "c(?(?!\\b|(?C)\\B(?C`x`))ab|a)", "cab" },
+ { MU, A, 0, 0, "a(?=)b", "ab" },
+ { MU, A, 0, 0 | F_NOMATCH, "a(?!)b", "ab" },
+
+ /* Not empty, ACCEPT, FAIL */
+ { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" },
+ { MU, A, PCRE2_NOTEMPTY, 0, "a*", "bcaad" },
+ { MU, A, PCRE2_NOTEMPTY, 0, "a*?", "bcaad" },
+ { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*", "bcaad" },
+ { MU, A, 0, 0, "a(*ACCEPT)b", "ab" },
+ { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*(*ACCEPT)b", "bcx" },
+ { MU, A, PCRE2_NOTEMPTY, 0, "a*(*ACCEPT)b", "bcaad" },
+ { MU, A, PCRE2_NOTEMPTY, 0, "a*?(*ACCEPT)b", "bcaad" },
+ { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "(?:z|a*(*ACCEPT)b)", "bcx" },
+ { MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*(*ACCEPT)b)", "bcaad" },
+ { MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*?(*ACCEPT)b)", "bcaad" },
+ { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*(*ACCEPT)b", "bcx" },
+ { MU, A, PCRE2_NOTEMPTY_ATSTART, 0 | F_NOMATCH, "a*(*ACCEPT)b", "" },
+ { MU, A, 0, 0, "((a(*ACCEPT)b))", "ab" },
+ { MU, A, 0, 0, "(a(*FAIL)a|a)", "aaa" },
+ { MU, A, 0, 0, "(?=ab(*ACCEPT)b)a", "ab" },
+ { MU, A, 0, 0, "(?=(?:x|ab(*ACCEPT)b))", "ab" },
+ { MU, A, 0, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" },
+ { MU, A, PCRE2_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" },
+
+ /* Conditional blocks. */
+ { MU, A, 0, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?!(b))a|b)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?=a)a|b)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?!b)a|b)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?=(a))a*|b*)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?!(b))a*|b*)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" },
+ { MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" },
+ { MU, A, 0, 0 | F_DIFF, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" },
+ { MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" },
+ { MU, A, 0, 0, "(?(?=a)a*|b*)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?!b)a*|b*)+k", "ababbalbbadabak" },
+ { MU, A, 0, 0, "(?(?=a)ab)", "a" },
+ { MU, A, 0, 0, "(?(?<!b)c)", "b" },
+ { MU, A, 0, 0, "(?(DEFINE)a(b))", "a" },
+ { MU, A, 0, 0, "a(?(DEFINE)(?:b|(?:c?)+)*)", "a" },
+ { MU, A, 0, 0, "(?(?=.[a-c])[k-l]|[A-D])", "kdB" },
+ { MU, A, 0, 0, "(?(?!.{0,4}[cd])(aa|bb)|(cc|dd))+", "aabbccddaa" },
+ { MU, A, 0, 0, "(?(?=[^#@]*@)(aaab|aa|aba)|(aba|aab)){3,}", "aaabaaaba#aaabaaaba#aaabaaaba@" },
+ { MU, A, 0, 0, "((?=\\w{5})\\w(?(?=\\w*k)\\d|[a-f_])*\\w\\s)+", "mol m10kk m088k _f_a_ mbkkl" },
+ { MU, A, 0, 0, "(c)?\?(?(1)a|b)", "cdcaa" },
+ { MU, A, 0, 0, "(c)?\?(?(1)a|b)", "cbb" },
+ { MU, A, 0, 0 | F_DIFF, "(?(?=(a))(aaaa|a?))+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0, "(?(?=a)(aaaa|a?))+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0, "(?(?!(b))(aaaa|a?))+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0, "(?(?!b)(aaaa|a?))+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0 | F_DIFF, "(?(?=(a))a*)+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0, "(?(?=a)a*)+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0, "(?(?!(b))a*)+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0, "(?(?!b)a*)+aak", "aaaaab aaaaak" },
+ { MU, A, 0, 0, "(?(?=(?=(?!(x))a)aa)aaa|(?(?=(?!y)bb)bbb))*k", "abaabbaaabbbaaabbb abaabbaaabbbaaabbbk" },
+ { MU, A, 0, 0, "(?P<Name>a)?(?P<Name2>b)?(?(Name)c|d)*l", "bc ddd abccabccl" },
+ { MU, A, 0, 0, "(?P<Name>a)?(?P<Name2>b)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" },
+ { MU, A, 0, 0, "(?P<Name>a)?(?P<Name2>b)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" },
+ { MU, A, 0, 0, "((?:a|aa)(?(1)aaa))x", "aax" },
+ { MU, A, 0, 0, "(?(?!)a|b)", "ab" },
+ { MU, A, 0, 0, "(?(?!)a)", "ab" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?(?!)a|b)", "ac" },
+
+ /* Set start of match. */
+ { MU, A, 0, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" },
+ { MU, A, 0, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" },
+ { MU, A, 0, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" },
+ { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a\\K(*ACCEPT)b", "aa" },
+ { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a\\K(*ACCEPT)b", "aa" },
+
+ /* First line. */
+ { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_PROPERTY, "\\p{Any}a", "bb\naaa" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}a", "bb\r\naaa" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0, "(?<=a)", "a" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[^a][^b]", "ab" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "a", "\na" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[abc]", "\na" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^a", "\na" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^(?<=\n)", "\na" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0, "\xf0\x90\x90\x80", "\xf0\x90\x90\x80" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\xc2\x85#" },
+ { M | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\x85#" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "^#", "\xe2\x80\xa8#" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_PROPERTY, "\\p{Any}", "\r\na" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, "a", "\ra" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH, "ba", "bbb\r\nba" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" },
+ { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 1, ".", "\r\n" },
+ { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_LF, 0, 0 | F_NOMATCH, "ab.", "ab" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" },
+ { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_ANY, 0, 0, "....a", "012\n0a" },
+ { MU | PCRE2_FIRSTLINE, A, 0, 0, "[aC]", "a" },
+
+ /* Recurse. */
+ { MU, A, 0, 0, "(a)(?1)", "aa" },
+ { MU, A, 0, 0, "((a))(?1)", "aa" },
+ { MU, A, 0, 0, "(b|a)(?1)", "aa" },
+ { MU, A, 0, 0, "(b|(a))(?1)", "aa" },
+ { MU, A, 0, 0 | F_NOMATCH, "((a)(b)(?:a*))(?1)", "aba" },
+ { MU, A, 0, 0, "((a)(b)(?:a*))(?1)", "abab" },
+ { MU, A, 0, 0, "((a+)c(?2))b(?1)", "aacaabaca" },
+ { MU, A, 0, 0, "((?2)b|(a)){2}(?1)", "aabab" },
+ { MU, A, 0, 0, "(?1)(a)*+(?2)(b(?1))", "aababa" },
+ { MU, A, 0, 0, "(?1)(((a(*ACCEPT)))b)", "axaa" },
+ { MU, A, 0, 0, "(?1)(?(DEFINE) (((ac(*ACCEPT)))b) )", "akaac" },
+ { MU, A, 0, 0, "(a+)b(?1)b\\1", "abaaabaaaaa" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)(aa|a))(?1)ab", "aab" },
+ { MU, A, 0, 0, "(?(DEFINE)(a\\Kb))(?1)+ababc", "abababxabababc" },
+ { MU, A, 0, 0, "(a\\Kb)(?1)+ababc", "abababxababababc" },
+ { MU, A, 0, 0 | F_NOMATCH, "(a\\Kb)(?1)+ababc", "abababxababababxc" },
+ { MU, A, 0, 0, "b|<(?R)*>", "<<b>" },
+ { MU, A, 0, 0, "(a\\K){0}(?:(?1)b|ac)", "ac" },
+ { MU, A, 0, 0, "(?(DEFINE)(a(?2)|b)(b(?1)|(a)))(?:(?1)|(?2))m", "ababababnababababaam" },
+ { MU, A, 0, 0, "(a)((?(R)a|b))(?2)", "aabbabaa" },
+ { MU, A, 0, 0, "(a)((?(R2)a|b))(?2)", "aabbabaa" },
+ { MU, A, 0, 0, "(a)((?(R1)a|b))(?2)", "ababba" },
+ { MU, A, 0, 0, "(?(R0)aa|bb(?R))", "abba aabb bbaa" },
+ { MU, A, 0, 0, "((?(R)(?:aaaa|a)|(?:(aaaa)|(a)))+)(?1)$", "aaaaaaaaaa aaaa" },
+ { MU, A, 0, 0, "(?P<Name>a(?(R&Name)a|b))(?1)", "aab abb abaa" },
+ { MU, A, 0, 0, "((?(R)a|(?1)){3})", "XaaaaaaaaaX" },
+ { MU, A, 0, 0, "((?:(?(R)a|(?1))){3})", "XaaaaaaaaaX" },
+ { MU, A, 0, 0, "((?(R)a|(?1)){1,3})aaaaaa", "aaaaaaaaXaaaaaaaaa" },
+ { MU, A, 0, 0, "((?(R)a|(?1)){1,3}?)M", "aaaM" },
+
+ /* 16 bit specific tests. */
+ { CM, A, 0, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" },
+ { CM, A, 0, 0 | F_FORCECONV, "\xe1\xbd\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" },
+ { CM, A, 0, 0 | F_FORCECONV, "[\xc3\xa1]", "\xc3\x81\xc3\xa1" },
+ { CM, A, 0, 0 | F_FORCECONV, "[\xe1\xbd\xb8]", "\xe1\xbf\xb8\xe1\xbd\xb8" },
+ { CM, A, 0, 0 | F_FORCECONV, "[a-\xed\xb0\x80]", "A" },
+ { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[a-\\x{dc00}]", "B" },
+ { CM, A, 0, 0 | F_NO8 | F_NOMATCH | F_FORCECONV, "[b-\\x{dc00}]", "a" },
+ { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "\xed\xa0\x80\\x{d800}\xed\xb0\x80\\x{dc00}", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80" },
+ { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\xed\xa0\x80\\x{d800}]{1,2}?[\xed\xb0\x80\\x{dc00}]{1,2}?#", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80#" },
+ { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80\xed\xb0\x80#]{0,3}(?<=\xed\xb0\x80.)", "\xed\xa0\x80#\xed\xa0\x80##\xed\xb0\x80\xed\xa0\x80" },
+ { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\x9f\xbf\xed\xa0\x83" },
+ { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\xb4\x80\xed\xb3\xb0" },
+ { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\x9f\xbf\xed\xa0\x83" },
+ { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\xb4\x80\xed\xb3\xb0" },
+ { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xef\xbf\xbf]+[\x1-\xed\xb0\x80]+#", "\xed\xa0\x85\xc3\x81\xed\xa0\x85\xef\xbf\xb0\xc2\x85\xed\xa9\x89#" },
+ { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80][\xed\xb0\x80]{2,}", "\xed\xa0\x80\xed\xb0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80\xed\xb0\x80" },
+ { M, A, 0, 0 | F_FORCECONV, "[^\xed\xb0\x80]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" },
+ { M, A, 0, 0 | F_NO8 | F_FORCECONV, "[^\\x{dc00}]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" },
+ { CM, A, 0, 0 | F_FORCECONV, ".\\B.", "\xed\xa0\x80\xed\xb0\x80" },
+ { CM, A, 0, 0 | F_FORCECONV, "\\D+(?:\\d+|.)\\S+(?:\\s+|.)\\W+(?:\\w+|.)\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80" },
+ { CM, A, 0, 0 | F_FORCECONV, "\\d*\\s*\\w*\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80" },
+ { CM, A, 0, 0 | F_FORCECONV | F_NOMATCH, "\\d*?\\D*?\\s*?\\S*?\\w*?\\W*?##", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80#" },
+ { CM | PCRE2_EXTENDED, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80 \xed\xb0\x80 !", "\xed\xa0\x80\xed\xb0\x80!" },
+ { CM, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80+#[^#]+\xed\xa0\x80", "\xed\xa0\x80#a\xed\xa0\x80" },
+ { CM, A, 0, 0 | F_FORCECONV, "(\xed\xa0\x80+)#\\1", "\xed\xa0\x80\xed\xa0\x80#\xed\xa0\x80\xed\xa0\x80" },
+ { M, PCRE2_NEWLINE_ANY, 0, 0 | F_NO8 | F_FORCECONV, "^-", "a--\xe2\x80\xa8--" },
+ { 0, BSR(PCRE2_BSR_UNICODE), 0, 0 | F_NO8 | F_FORCECONV, "\\R", "ab\xe2\x80\xa8" },
+ { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v", "ab\xe2\x80\xa9" },
+ { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h", "ab\xe1\xa0\x8e" },
+ { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v+?\\V+?#", "\xe2\x80\xa9\xe2\x80\xa9\xef\xbf\xbf\xef\xbf\xbf#" },
+ { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h+?\\H+?#", "\xe1\xa0\x8e\xe1\xa0\x8e\xef\xbf\xbf\xef\xbf\xbf#" },
+
+ /* Partial matching. */
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "ab", "a" },
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "ab|a", "a" },
+ { MU, A, PCRE2_PARTIAL_HARD, 0, "ab|a", "a" },
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "\\b#", "a" },
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "(?<=a)b", "a" },
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "abc|(?<=xxa)bc", "xxab" },
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "a\\B", "a" },
+ { MU, A, PCRE2_PARTIAL_HARD, 0, "a\\b", "a" },
+
+ /* (*MARK) verb. */
+ { MU, A, 0, 0, "a(*MARK:aa)a", "ababaa" },
+ { MU, A, 0, 0 | F_NOMATCH, "a(*:aa)a", "abab" },
+ { MU, A, 0, 0, "a(*:aa)(b(*:bb)b|bc)", "abc" },
+ { MU, A, 0, 0 | F_NOMATCH, "a(*:1)x|b(*:2)y", "abc" },
+ { MU, A, 0, 0, "(?>a(*:aa))b|ac", "ac" },
+ { MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))(?1)", "a" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)((a)(*:aa)))(?1)b", "aa" },
+ { MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" },
+ { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" },
+ { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" },
+ { MU, A, 0, 0 | F_NOMATCH, "(a(*:aa)){0}(?:b(?1)b)+", "ba" },
+ { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" },
+ { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" },
+ { MU, A, 0, 0 | F_NOMATCH, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*:mark)m", "a" },
+
+ /* (*COMMIT) verb. */
+ { MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" },
+ { MU, A, 0, 0, "aa(*COMMIT)b", "xaxaab" },
+ { MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" },
+ { MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b)++", "abac" },
+ { MU, A, 0, 0 | F_NOMATCH, "((a)(*COMMIT)b)++", "abac" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?=a(*COMMIT)b)ab|ad", "ad" },
+
+ /* (*PRUNE) verb. */
+ { MU, A, 0, 0, "aa\\K(*PRUNE)b", "aaab" },
+ { MU, A, 0, 0, "aa(*PRUNE:bb)b|a", "aa" },
+ { MU, A, 0, 0, "(a)(a)(*PRUNE)b|(a)", "aa" },
+ { MU, A, 0, 0, "(a)(a)(a)(a)(a)(a)(a)(a)(*PRUNE)b|(a)", "aaaaaaaa" },
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|", "a" },
+ { MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|m", "a" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?=a(*PRUNE)b)ab|ad", "ad" },
+ { MU, A, 0, 0, "a(*COMMIT)(*PRUNE)d|bc", "abc" },
+ { MU, A, 0, 0, "(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" },
+ { MU, A, 0, 0, "(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" },
+ { MU, A, 0, 0, "(a(*COMMIT)b){0}a(?1)(*PRUNE)c|bc", "abc" },
+ { MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b){0}a(*COMMIT)(?1)(*PRUNE)c|bc", "abc" },
+ { MU, A, 0, 0, "(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" },
+ { MU, A, 0, 0, "((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" },
+ { MU, A, 0, 0, "(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" },
+ { MU, A, 0, 0, "(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" },
+ { MU, A, 0, 0, "(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" },
+ { MU, A, 0, 0, "(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" },
+ { MU, A, 0, 0, "(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" },
+ { MU, A, 0, 0, "(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" },
+ { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" },
+
+ /* (*SKIP) verb. */
+ { MU, A, 0, 0 | F_NOMATCH, "(?=a(*SKIP)b)ab|ad", "ad" },
+ { MU, A, 0, 0, "(\\w+(*SKIP)#)", "abcd,xyz#," },
+ { MU, A, 0, 0, "\\w+(*SKIP)#|mm", "abcd,xyz#," },
+ { MU, A, 0, 0 | F_NOMATCH, "b+(?<=(*SKIP)#c)|b+", "#bbb" },
+
+ /* (*THEN) verb. */
+ { MU, A, 0, 0, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcaabcaabcaabcnacm" },
+ { MU, A, 0, 0 | F_NOMATCH, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcm" },
+ { MU, A, 0, 0, "((?:a(*THEN)|aab)c|a+)+m", "aabcaabcnmaabcaabcm" },
+ { MU, A, 0, 0, "((?:a|aab)(*THEN)c|a+)+m", "aam" },
+ { MU, A, 0, 0, "((?:a(*COMMIT)|aab)(*THEN)c|a+)+m", "aam" },
+ { MU, A, 0, 0, "(?(?=a(*THEN)b)ab|ad)", "ad" },
+ { MU, A, 0, 0, "(?(?!a(*THEN)b)ad|add)", "add" },
+ { MU, A, 0, 0 | F_NOMATCH, "(?(?=a)a(*THEN)b|ad)", "ad" },
+ { MU, A, 0, 0, "(?!(?(?=a)ab|b(*THEN)d))bn|bnn", "bnn" },
+
+ /* Deep recursion. */
+ { MU, A, 0, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " },
+ { MU, A, 0, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " },
+ { MU, A, 0, 0, "((a?)+)+b", "aaaaaaaaaaaa b" },
+
+ /* Deep recursion: Stack limit reached. */
+ { M, A, 0, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" },
+ { M, A, 0, 0 | F_NOMATCH, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+ { M, A, 0, 0 | F_NOMATCH, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+ { M, A, 0, 0 | F_NOMATCH, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+ { M, A, 0, 0 | F_NOMATCH, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+
+ { 0, 0, 0, 0, NULL, NULL }
+};
+
+#ifdef SUPPORT_PCRE2_8
+static pcre2_jit_stack_8* callback8(void *arg)
+{
+ return (pcre2_jit_stack_8 *)arg;
+}
+#endif
+
+#ifdef SUPPORT_PCRE2_16
+static pcre2_jit_stack_16* callback16(void *arg)
+{
+ return (pcre2_jit_stack_16 *)arg;
+}
+#endif
+
+#ifdef SUPPORT_PCRE2_32
+static pcre2_jit_stack_32* callback32(void *arg)
+{
+ return (pcre2_jit_stack_32 *)arg;
+}
+#endif
+
+#ifdef SUPPORT_PCRE2_8
+static pcre2_jit_stack_8 *stack8;
+
+static pcre2_jit_stack_8 *getstack8(void)
+{
+ if (!stack8)
+ stack8 = pcre2_jit_stack_create_8(1, 1024 * 1024, NULL);
+ return stack8;
+}
+
+static void setstack8(pcre2_match_context_8 *mcontext)
+{
+ if (!mcontext) {
+ if (stack8)
+ pcre2_jit_stack_free_8(stack8);
+ stack8 = NULL;
+ return;
+ }
+
+ pcre2_jit_stack_assign_8(mcontext, callback8, getstack8());
+}
+#endif /* SUPPORT_PCRE2_8 */
+
+#ifdef SUPPORT_PCRE2_16
+static pcre2_jit_stack_16 *stack16;
+
+static pcre2_jit_stack_16 *getstack16(void)
+{
+ if (!stack16)
+ stack16 = pcre2_jit_stack_create_16(1, 1024 * 1024, NULL);
+ return stack16;
+}
+
+static void setstack16(pcre2_match_context_16 *mcontext)
+{
+ if (!mcontext) {
+ if (stack16)
+ pcre2_jit_stack_free_16(stack16);
+ stack16 = NULL;
+ return;
+ }
+
+ pcre2_jit_stack_assign_16(mcontext, callback16, getstack16());
+}
+#endif /* SUPPORT_PCRE2_16 */
+
+#ifdef SUPPORT_PCRE2_32
+static pcre2_jit_stack_32 *stack32;
+
+static pcre2_jit_stack_32 *getstack32(void)
+{
+ if (!stack32)
+ stack32 = pcre2_jit_stack_create_32(1, 1024 * 1024, NULL);
+ return stack32;
+}
+
+static void setstack32(pcre2_match_context_32 *mcontext)
+{
+ if (!mcontext) {
+ if (stack32)
+ pcre2_jit_stack_free_32(stack32);
+ stack32 = NULL;
+ return;
+ }
+
+ pcre2_jit_stack_assign_32(mcontext, callback32, getstack32());
+}
+#endif /* SUPPORT_PCRE2_32 */
+
+#ifdef SUPPORT_PCRE2_16
+
+static int convert_utf8_to_utf16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int *offsetmap, int max_length)
+{
+ PCRE2_SPTR8 iptr = input;
+ PCRE2_UCHAR16 *optr = output;
+ unsigned int c;
+
+ if (max_length == 0)
+ return 0;
+
+ while (*iptr && max_length > 1) {
+ c = 0;
+ if (offsetmap)
+ *offsetmap++ = (int)(iptr - (unsigned char*)input);
+
+ if (*iptr < 0xc0)
+ c = *iptr++;
+ else if (!(*iptr & 0x20)) {
+ c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f);
+ iptr += 2;
+ } else if (!(*iptr & 0x10)) {
+ c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f);
+ iptr += 3;
+ } else if (!(*iptr & 0x08)) {
+ c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f);
+ iptr += 4;
+ }
+
+ if (c < 65536) {
+ *optr++ = c;
+ max_length--;
+ } else if (max_length <= 2) {
+ *optr = '\0';
+ return (int)(optr - output);
+ } else {
+ c -= 0x10000;
+ *optr++ = 0xd800 | ((c >> 10) & 0x3ff);
+ *optr++ = 0xdc00 | (c & 0x3ff);
+ max_length -= 2;
+ if (offsetmap)
+ offsetmap++;
+ }
+ }
+ if (offsetmap)
+ *offsetmap = (int)(iptr - (unsigned char*)input);
+ *optr = '\0';
+ return (int)(optr - output);
+}
+
+static int copy_char8_to_char16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int max_length)
+{
+ PCRE2_SPTR8 iptr = input;
+ PCRE2_UCHAR16 *optr = output;
+
+ if (max_length == 0)
+ return 0;
+
+ while (*iptr && max_length > 1) {
+ *optr++ = *iptr++;
+ max_length--;
+ }
+ *optr = '\0';
+ return (int)(optr - output);
+}
+
+#define REGTEST_MAX_LENGTH16 4096
+static PCRE2_UCHAR16 regtest_buf16[REGTEST_MAX_LENGTH16];
+static int regtest_offsetmap16[REGTEST_MAX_LENGTH16];
+
+#endif /* SUPPORT_PCRE2_16 */
+
+#ifdef SUPPORT_PCRE2_32
+
+static int convert_utf8_to_utf32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int *offsetmap, int max_length)
+{
+ PCRE2_SPTR8 iptr = input;
+ PCRE2_UCHAR32 *optr = output;
+ unsigned int c;
+
+ if (max_length == 0)
+ return 0;
+
+ while (*iptr && max_length > 1) {
+ c = 0;
+ if (offsetmap)
+ *offsetmap++ = (int)(iptr - (unsigned char*)input);
+
+ if (*iptr < 0xc0)
+ c = *iptr++;
+ else if (!(*iptr & 0x20)) {
+ c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f);
+ iptr += 2;
+ } else if (!(*iptr & 0x10)) {
+ c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f);
+ iptr += 3;
+ } else if (!(*iptr & 0x08)) {
+ c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f);
+ iptr += 4;
+ }
+
+ *optr++ = c;
+ max_length--;
+ }
+ if (offsetmap)
+ *offsetmap = (int)(iptr - (unsigned char*)input);
+ *optr = 0;
+ return (int)(optr - output);
+}
+
+static int copy_char8_to_char32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int max_length)
+{
+ PCRE2_SPTR8 iptr = input;
+ PCRE2_UCHAR32 *optr = output;
+
+ if (max_length == 0)
+ return 0;
+
+ while (*iptr && max_length > 1) {
+ *optr++ = *iptr++;
+ max_length--;
+ }
+ *optr = '\0';
+ return (int)(optr - output);
+}
+
+#define REGTEST_MAX_LENGTH32 4096
+static PCRE2_UCHAR32 regtest_buf32[REGTEST_MAX_LENGTH32];
+static int regtest_offsetmap32[REGTEST_MAX_LENGTH32];
+
+#endif /* SUPPORT_PCRE2_32 */
+
+static int check_ascii(const char *input)
+{
+ const unsigned char *ptr = (unsigned char *)input;
+ while (*ptr) {
+ if (*ptr > 127)
+ return 0;
+ ptr++;
+ }
+ return 1;
+}
+
+#define OVECTOR_SIZE 15
+
+static int regression_tests(void)
+{
+ struct regression_test_case *current = regression_test_cases;
+ int error;
+ PCRE2_SIZE err_offs;
+ int is_successful;
+ int is_ascii;
+ int total = 0;
+ int successful = 0;
+ int successful_row = 0;
+ int counter = 0;
+ int jit_compile_mode;
+ int utf = 0;
+ int disabled_options = 0;
+ int i;
+#ifdef SUPPORT_PCRE2_8
+ pcre2_code_8 *re8;
+ pcre2_compile_context_8 *ccontext8;
+ pcre2_match_data_8 *mdata8_1;
+ pcre2_match_data_8 *mdata8_2;
+ pcre2_match_context_8 *mcontext8;
+ PCRE2_SIZE *ovector8_1 = NULL;
+ PCRE2_SIZE *ovector8_2 = NULL;
+ int return_value8[2];
+#endif
+#ifdef SUPPORT_PCRE2_16
+ pcre2_code_16 *re16;
+ pcre2_compile_context_16 *ccontext16;
+ pcre2_match_data_16 *mdata16_1;
+ pcre2_match_data_16 *mdata16_2;
+ pcre2_match_context_16 *mcontext16;
+ PCRE2_SIZE *ovector16_1 = NULL;
+ PCRE2_SIZE *ovector16_2 = NULL;
+ int return_value16[2];
+ int length16;
+#endif
+#ifdef SUPPORT_PCRE2_32
+ pcre2_code_32 *re32;
+ pcre2_compile_context_32 *ccontext32;
+ pcre2_match_data_32 *mdata32_1;
+ pcre2_match_data_32 *mdata32_2;
+ pcre2_match_context_32 *mcontext32;
+ PCRE2_SIZE *ovector32_1 = NULL;
+ PCRE2_SIZE *ovector32_2 = NULL;
+ int return_value32[2];
+ int length32;
+#endif
+
+#if defined SUPPORT_PCRE2_8
+ PCRE2_UCHAR8 cpu_info[128];
+#elif defined SUPPORT_PCRE2_16
+ PCRE2_UCHAR16 cpu_info[128];
+#elif defined SUPPORT_PCRE2_32
+ PCRE2_UCHAR32 cpu_info[128];
+#endif
+#if defined SUPPORT_UTF && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2)
+ int return_value;
+#endif
+
+ /* This test compares the behaviour of interpreter and JIT. Although disabling
+ utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is
+ still considered successful from pcre_jit_test point of view. */
+
+#if defined SUPPORT_PCRE2_8
+ pcre2_config_8(PCRE2_CONFIG_JITTARGET, &cpu_info);
+#elif defined SUPPORT_PCRE2_16
+ pcre2_config_16(PCRE2_CONFIG_JITTARGET, &cpu_info);
+#elif defined SUPPORT_PCRE2_32
+ pcre2_config_32(PCRE2_CONFIG_JITTARGET, &cpu_info);
+#endif
+
+ printf("Running JIT regression tests\n");
+ printf(" target CPU of SLJIT compiler: ");
+ for (i = 0; cpu_info[i]; i++)
+ printf("%c", (char)(cpu_info[i]));
+ printf("\n");
+
+#if defined SUPPORT_PCRE2_8
+ pcre2_config_8(PCRE2_CONFIG_UNICODE, &utf);
+#elif defined SUPPORT_PCRE2_16
+ pcre2_config_16(PCRE2_CONFIG_UNICODE, &utf);
+#elif defined SUPPORT_PCRE2_32
+ pcre2_config_32(PCRE2_CONFIG_UNICODE, &utf);
+#endif
+
+ if (!utf)
+ disabled_options |= PCRE2_UTF;
+#ifdef SUPPORT_PCRE2_8
+ printf(" in 8 bit mode with UTF-8 %s:\n", utf ? "enabled" : "disabled");
+#endif
+#ifdef SUPPORT_PCRE2_16
+ printf(" in 16 bit mode with UTF-16 %s:\n", utf ? "enabled" : "disabled");
+#endif
+#ifdef SUPPORT_PCRE2_32
+ printf(" in 32 bit mode with UTF-32 %s:\n", utf ? "enabled" : "disabled");
+#endif
+
+ while (current->pattern) {
+ /* printf("\nPattern: %s :\n", current->pattern); */
+ total++;
+ is_ascii = 0;
+ if (!(current->start_offset & F_PROPERTY))
+ is_ascii = check_ascii(current->pattern) && check_ascii(current->input);
+
+ if (current->match_options & PCRE2_PARTIAL_SOFT)
+ jit_compile_mode = PCRE2_JIT_PARTIAL_SOFT;
+ else if (current->match_options & PCRE2_PARTIAL_HARD)
+ jit_compile_mode = PCRE2_JIT_PARTIAL_HARD;
+ else
+ jit_compile_mode = PCRE2_JIT_COMPLETE;
+ error = 0;
+#ifdef SUPPORT_PCRE2_8
+ re8 = NULL;
+ ccontext8 = pcre2_compile_context_create_8(NULL);
+ if (ccontext8) {
+ if (GET_NEWLINE(current->newline))
+ pcre2_set_newline_8(ccontext8, GET_NEWLINE(current->newline));
+ if (GET_BSR(current->newline))
+ pcre2_set_bsr_8(ccontext8, GET_BSR(current->newline));
+
+ if (!(current->start_offset & F_NO8)) {
+ re8 = pcre2_compile_8((PCRE2_SPTR8)current->pattern, PCRE2_ZERO_TERMINATED,
+ current->compile_options & ~disabled_options,
+ &error, &err_offs, ccontext8);
+
+ if (!re8 && (utf || is_ascii))
+ printf("\n8 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error);
+ }
+ pcre2_compile_context_free_8(ccontext8);
+ }
+ else
+ printf("\n8 bit: Cannot allocate compile context\n");
+#endif
+#ifdef SUPPORT_PCRE2_16
+ if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))
+ convert_utf8_to_utf16((PCRE2_SPTR8)current->pattern, regtest_buf16, NULL, REGTEST_MAX_LENGTH16);
+ else
+ copy_char8_to_char16((PCRE2_SPTR8)current->pattern, regtest_buf16, REGTEST_MAX_LENGTH16);
+
+ re16 = NULL;
+ ccontext16 = pcre2_compile_context_create_16(NULL);
+ if (ccontext16) {
+ if (GET_NEWLINE(current->newline))
+ pcre2_set_newline_16(ccontext16, GET_NEWLINE(current->newline));
+ if (GET_BSR(current->newline))
+ pcre2_set_bsr_16(ccontext16, GET_BSR(current->newline));
+
+ if (!(current->start_offset & F_NO16)) {
+ re16 = pcre2_compile_16(regtest_buf16, PCRE2_ZERO_TERMINATED,
+ current->compile_options & ~disabled_options,
+ &error, &err_offs, ccontext16);
+
+ if (!re16 && (utf || is_ascii))
+ printf("\n16 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error);
+ }
+ pcre2_compile_context_free_16(ccontext16);
+ }
+ else
+ printf("\n16 bit: Cannot allocate compile context\n");
+#endif
+#ifdef SUPPORT_PCRE2_32
+ if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))
+ convert_utf8_to_utf32((PCRE2_SPTR8)current->pattern, regtest_buf32, NULL, REGTEST_MAX_LENGTH32);
+ else
+ copy_char8_to_char32((PCRE2_SPTR8)current->pattern, regtest_buf32, REGTEST_MAX_LENGTH32);
+
+ re32 = NULL;
+ ccontext32 = pcre2_compile_context_create_32(NULL);
+ if (ccontext32) {
+ if (GET_NEWLINE(current->newline))
+ pcre2_set_newline_32(ccontext32, GET_NEWLINE(current->newline));
+ if (GET_BSR(current->newline))
+ pcre2_set_bsr_32(ccontext32, GET_BSR(current->newline));
+
+ if (!(current->start_offset & F_NO32)) {
+ re32 = pcre2_compile_32(regtest_buf32, PCRE2_ZERO_TERMINATED,
+ current->compile_options & ~disabled_options,
+ &error, &err_offs, ccontext32);
+
+ if (!re32 && (utf || is_ascii))
+ printf("\n32 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error);
+ }
+ pcre2_compile_context_free_32(ccontext32);
+ }
+ else
+ printf("\n32 bit: Cannot allocate compile context\n");
+#endif
+
+ counter++;
+ if ((counter & 0x3) != 0) {
+#ifdef SUPPORT_PCRE2_8
+ setstack8(NULL);
+#endif
+#ifdef SUPPORT_PCRE2_16
+ setstack16(NULL);
+#endif
+#ifdef SUPPORT_PCRE2_32
+ setstack32(NULL);
+#endif
+ }
+
+#ifdef SUPPORT_PCRE2_8
+ return_value8[0] = -1000;
+ return_value8[1] = -1000;
+ mdata8_1 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL);
+ mdata8_2 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL);
+ mcontext8 = pcre2_match_context_create_8(NULL);
+ if (!mdata8_1 || !mdata8_2 || !mcontext8) {
+ printf("\n8 bit: Cannot allocate match data\n");
+ pcre2_match_data_free_8(mdata8_1);
+ pcre2_match_data_free_8(mdata8_2);
+ pcre2_match_context_free_8(mcontext8);
+ pcre2_code_free_8(re8);
+ re8 = NULL;
+ } else {
+ ovector8_1 = pcre2_get_ovector_pointer_8(mdata8_1);
+ ovector8_2 = pcre2_get_ovector_pointer_8(mdata8_2);
+ for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+ ovector8_1[i] = -2;
+ for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+ ovector8_2[i] = -2;
+ }
+ if (re8) {
+ return_value8[1] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input),
+ current->start_offset & OFFSET_MASK, current->match_options, mdata8_2, NULL);
+
+ if (pcre2_jit_compile_8(re8, jit_compile_mode)) {
+ printf("\n8 bit: JIT compiler does not support \"%s\"\n", current->pattern);
+ } else if ((counter & 0x1) != 0) {
+ setstack8(mcontext8);
+ return_value8[0] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input),
+ current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8);
+ } else {
+ pcre2_jit_stack_assign_8(mcontext8, NULL, getstack8());
+ return_value8[0] = pcre2_jit_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input),
+ current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8);
+ }
+ }
+#endif
+
+#ifdef SUPPORT_PCRE2_16
+ return_value16[0] = -1000;
+ return_value16[1] = -1000;
+ mdata16_1 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL);
+ mdata16_2 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL);
+ mcontext16 = pcre2_match_context_create_16(NULL);
+ if (!mdata16_1 || !mdata16_2 || !mcontext16) {
+ printf("\n16 bit: Cannot allocate match data\n");
+ pcre2_match_data_free_16(mdata16_1);
+ pcre2_match_data_free_16(mdata16_2);
+ pcre2_match_context_free_16(mcontext16);
+ pcre2_code_free_16(re16);
+ re16 = NULL;
+ } else {
+ ovector16_1 = pcre2_get_ovector_pointer_16(mdata16_1);
+ ovector16_2 = pcre2_get_ovector_pointer_16(mdata16_2);
+ for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+ ovector16_1[i] = -2;
+ for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+ ovector16_2[i] = -2;
+ }
+ if (re16) {
+ if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))
+ length16 = convert_utf8_to_utf16((PCRE2_SPTR8)current->input, regtest_buf16, regtest_offsetmap16, REGTEST_MAX_LENGTH16);
+ else
+ length16 = copy_char8_to_char16((PCRE2_SPTR8)current->input, regtest_buf16, REGTEST_MAX_LENGTH16);
+
+ return_value16[1] = pcre2_match_16(re16, regtest_buf16, length16,
+ current->start_offset & OFFSET_MASK, current->match_options, mdata16_2, NULL);
+
+ if (pcre2_jit_compile_16(re16, jit_compile_mode)) {
+ printf("\n16 bit: JIT compiler does not support \"%s\"\n", current->pattern);
+ } else if ((counter & 0x1) != 0) {
+ setstack16(mcontext16);
+ return_value16[0] = pcre2_match_16(re16, regtest_buf16, length16,
+ current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16);
+ } else {
+ pcre2_jit_stack_assign_16(mcontext16, NULL, getstack16());
+ return_value16[0] = pcre2_jit_match_16(re16, regtest_buf16, length16,
+ current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16);
+ }
+ }
+#endif
+
+#ifdef SUPPORT_PCRE2_32
+ return_value32[0] = -1000;
+ return_value32[1] = -1000;
+ mdata32_1 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL);
+ mdata32_2 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL);
+ mcontext32 = pcre2_match_context_create_32(NULL);
+ if (!mdata32_1 || !mdata32_2 || !mcontext32) {
+ printf("\n32 bit: Cannot allocate match data\n");
+ pcre2_match_data_free_32(mdata32_1);
+ pcre2_match_data_free_32(mdata32_2);
+ pcre2_match_context_free_32(mcontext32);
+ pcre2_code_free_32(re32);
+ re32 = NULL;
+ } else {
+ ovector32_1 = pcre2_get_ovector_pointer_32(mdata32_1);
+ ovector32_2 = pcre2_get_ovector_pointer_32(mdata32_2);
+ for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+ ovector32_1[i] = -2;
+ for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+ ovector32_2[i] = -2;
+ }
+ if (re32) {
+ if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))
+ length32 = convert_utf8_to_utf32((PCRE2_SPTR8)current->input, regtest_buf32, regtest_offsetmap32, REGTEST_MAX_LENGTH32);
+ else
+ length32 = copy_char8_to_char32((PCRE2_SPTR8)current->input, regtest_buf32, REGTEST_MAX_LENGTH32);
+
+ return_value32[1] = pcre2_match_32(re32, regtest_buf32, length32,
+ current->start_offset & OFFSET_MASK, current->match_options, mdata32_2, NULL);
+
+ if (pcre2_jit_compile_32(re32, jit_compile_mode)) {
+ printf("\n32 bit: JIT compiler does not support \"%s\"\n", current->pattern);
+ } else if ((counter & 0x1) != 0) {
+ setstack32(mcontext32);
+ return_value32[0] = pcre2_match_32(re32, regtest_buf32, length32,
+ current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32);
+ } else {
+ pcre2_jit_stack_assign_32(mcontext32, NULL, getstack32());
+ return_value32[0] = pcre2_jit_match_32(re32, regtest_buf32, length32,
+ current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32);
+ }
+ }
+#endif
+
+ /* printf("[%d-%d-%d|%d-%d|%d-%d|%d-%d]%s",
+ return_value8[0], return_value16[0], return_value32[0],
+ (int)ovector8_1[0], (int)ovector8_1[1],
+ (int)ovector16_1[0], (int)ovector16_1[1],
+ (int)ovector32_1[0], (int)ovector32_1[1],
+ (current->compile_options & PCRE2_CASELESS) ? "C" : ""); */
+
+ /* If F_DIFF is set, just run the test, but do not compare the results.
+ Segfaults can still be captured. */
+
+ is_successful = 1;
+ if (!(current->start_offset & F_DIFF)) {
+#if defined SUPPORT_UTF && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2)
+ if (!(current->start_offset & F_FORCECONV)) {
+
+ /* All results must be the same. */
+#ifdef SUPPORT_PCRE2_8
+ if ((return_value = return_value8[0]) != return_value8[1]) {
+ printf("\n8 bit: Return value differs(J8:%d,I8:%d): [%d] '%s' @ '%s'\n",
+ return_value8[0], return_value8[1], total, current->pattern, current->input);
+ is_successful = 0;
+ } else
+#endif
+#ifdef SUPPORT_PCRE2_16
+ if ((return_value = return_value16[0]) != return_value16[1]) {
+ printf("\n16 bit: Return value differs(J16:%d,I16:%d): [%d] '%s' @ '%s'\n",
+ return_value16[0], return_value16[1], total, current->pattern, current->input);
+ is_successful = 0;
+ } else
+#endif
+#ifdef SUPPORT_PCRE2_32
+ if ((return_value = return_value32[0]) != return_value32[1]) {
+ printf("\n32 bit: Return value differs(J32:%d,I32:%d): [%d] '%s' @ '%s'\n",
+ return_value32[0], return_value32[1], total, current->pattern, current->input);
+ is_successful = 0;
+ } else
+#endif
+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16
+ if (return_value8[0] != return_value16[0]) {
+ printf("\n8 and 16 bit: Return value differs(J8:%d,J16:%d): [%d] '%s' @ '%s'\n",
+ return_value8[0], return_value16[0],
+ total, current->pattern, current->input);
+ is_successful = 0;
+ } else
+#endif
+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32
+ if (return_value8[0] != return_value32[0]) {
+ printf("\n8 and 32 bit: Return value differs(J8:%d,J32:%d): [%d] '%s' @ '%s'\n",
+ return_value8[0], return_value32[0],
+ total, current->pattern, current->input);
+ is_successful = 0;
+ } else
+#endif
+#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_32
+ if (return_value16[0] != return_value32[0]) {
+ printf("\n16 and 32 bit: Return value differs(J16:%d,J32:%d): [%d] '%s' @ '%s'\n",
+ return_value16[0], return_value32[0],
+ total, current->pattern, current->input);
+ is_successful = 0;
+ } else
+#endif
+ if (return_value >= 0 || return_value == PCRE_ERROR_PARTIAL) {
+ if (return_value == PCRE_ERROR_PARTIAL) {
+ return_value = 2;
+ } else {
+ return_value *= 2;
+ }
+#ifdef SUPPORT_PCRE2_8
+ return_value8[0] = return_value;
+#endif
+#ifdef SUPPORT_PCRE2_16
+ return_value16[0] = return_value;
+#endif
+#ifdef SUPPORT_PCRE2_32
+ return_value32[0] = return_value;
+#endif
+ /* Transform back the results. */
+ if (current->flags & PCRE_UTF8) {
+#ifdef SUPPORT_PCRE2_16
+ for (i = 0; i < return_value; ++i) {
+ if (ovector16_1[i] >= 0)
+ ovector16_1[i] = regtest_offsetmap16[ovector16_1[i]];
+ if (ovector16_2[i] >= 0)
+ ovector16_2[i] = regtest_offsetmap16[ovector16_2[i]];
+ }
+#endif
+#ifdef SUPPORT_PCRE2_32
+ for (i = 0; i < return_value; ++i) {
+ if (ovector32_1[i] >= 0)
+ ovector32_1[i] = regtest_offsetmap32[ovector32_1[i]];
+ if (ovector32_2[i] >= 0)
+ ovector32_2[i] = regtest_offsetmap32[ovector32_2[i]];
+ }
+#endif
+ }
+
+ for (i = 0; i < return_value; ++i) {
+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16
+ if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) {
+ printf("\n8 and 16 bit: Ovector[%d] value differs(J8:%d,I8:%d,J16:%d,I16:%d): [%d] '%s' @ '%s' \n",
+ i, ovector8_1[i], ovector8_2[i], ovector16_1[i], ovector16_2[i],
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32
+ if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector32_1[i] || ovector8_1[i] != ovector32_2[i]) {
+ printf("\n8 and 32 bit: Ovector[%d] value differs(J8:%d,I8:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n",
+ i, ovector8_1[i], ovector8_2[i], ovector32_1[i], ovector32_2[i],
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_32
+ if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector32_1[i] || ovector16_1[i] != ovector32_2[i]) {
+ printf("\n16 and 32 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n",
+ i, ovector16_1[i], ovector16_2[i], ovector32_1[i], ovector32_2[i],
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+ }
+ }
+ } else
+#endif /* more than one of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16 and SUPPORT_PCRE2_32 */
+ {
+#ifdef SUPPORT_PCRE2_8
+ if (return_value8[0] != return_value8[1]) {
+ printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ return_value8[0], return_value8[1], total, current->pattern, current->input);
+ is_successful = 0;
+ } else if (return_value8[0] >= 0 || return_value8[0] == PCRE2_ERROR_PARTIAL) {
+ if (return_value8[0] == PCRE2_ERROR_PARTIAL)
+ return_value8[0] = 2;
+ else
+ return_value8[0] *= 2;
+
+ for (i = 0; i < return_value8[0]; ++i)
+ if (ovector8_1[i] != ovector8_2[i]) {
+ printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ i, (int)ovector8_1[i], (int)ovector8_2[i], total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+
+#ifdef SUPPORT_PCRE2_16
+ if (return_value16[0] != return_value16[1]) {
+ printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ return_value16[0], return_value16[1], total, current->pattern, current->input);
+ is_successful = 0;
+ } else if (return_value16[0] >= 0 || return_value16[0] == PCRE2_ERROR_PARTIAL) {
+ if (return_value16[0] == PCRE2_ERROR_PARTIAL)
+ return_value16[0] = 2;
+ else
+ return_value16[0] *= 2;
+
+ for (i = 0; i < return_value16[0]; ++i)
+ if (ovector16_1[i] != ovector16_2[i]) {
+ printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ i, (int)ovector16_1[i], (int)ovector16_2[i], total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+
+#ifdef SUPPORT_PCRE2_32
+ if (return_value32[0] != return_value32[1]) {
+ printf("\n32 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ return_value32[0], return_value32[1], total, current->pattern, current->input);
+ is_successful = 0;
+ } else if (return_value32[0] >= 0 || return_value32[0] == PCRE2_ERROR_PARTIAL) {
+ if (return_value32[0] == PCRE2_ERROR_PARTIAL)
+ return_value32[0] = 2;
+ else
+ return_value32[0] *= 2;
+
+ for (i = 0; i < return_value32[0]; ++i)
+ if (ovector32_1[i] != ovector32_2[i]) {
+ printf("\n32 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ i, (int)ovector32_1[i], (int)ovector32_2[i], total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+ }
+ }
+
+ if (is_successful) {
+#ifdef SUPPORT_PCRE2_8
+ if (!(current->start_offset & F_NO8) && (utf || is_ascii)) {
+ if (return_value8[0] < 0 && !(current->start_offset & F_NOMATCH)) {
+ printf("8 bit: Test should match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+
+ if (return_value8[0] >= 0 && (current->start_offset & F_NOMATCH)) {
+ printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+#ifdef SUPPORT_PCRE2_16
+ if (!(current->start_offset & F_NO16) && (utf || is_ascii)) {
+ if (return_value16[0] < 0 && !(current->start_offset & F_NOMATCH)) {
+ printf("16 bit: Test should match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+
+ if (return_value16[0] >= 0 && (current->start_offset & F_NOMATCH)) {
+ printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+#ifdef SUPPORT_PCRE2_32
+ if (!(current->start_offset & F_NO32) && (utf || is_ascii)) {
+ if (return_value32[0] < 0 && !(current->start_offset & F_NOMATCH)) {
+ printf("32 bit: Test should match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+
+ if (return_value32[0] >= 0 && (current->start_offset & F_NOMATCH)) {
+ printf("32 bit: Test should not match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+ }
+
+ if (is_successful) {
+#ifdef SUPPORT_PCRE2_8
+ if (re8 && !(current->start_offset & F_NO8) && pcre2_get_mark_8(mdata8_1) != pcre2_get_mark_8(mdata8_2)) {
+ printf("8 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+#ifdef SUPPORT_PCRE2_16
+ if (re16 && !(current->start_offset & F_NO16) && pcre2_get_mark_16(mdata16_1) != pcre2_get_mark_16(mdata16_2)) {
+ printf("16 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+#ifdef SUPPORT_PCRE2_32
+ if (re32 && !(current->start_offset & F_NO32) && pcre2_get_mark_32(mdata32_1) != pcre2_get_mark_32(mdata32_2)) {
+ printf("32 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+ }
+
+#ifdef SUPPORT_PCRE2_8
+ pcre2_code_free_8(re8);
+ pcre2_match_data_free_8(mdata8_1);
+ pcre2_match_data_free_8(mdata8_2);
+ pcre2_match_context_free_8(mcontext8);
+#endif
+#ifdef SUPPORT_PCRE2_16
+ pcre2_code_free_16(re16);
+ pcre2_match_data_free_16(mdata16_1);
+ pcre2_match_data_free_16(mdata16_2);
+ pcre2_match_context_free_16(mcontext16);
+#endif
+#ifdef SUPPORT_PCRE2_32
+ pcre2_code_free_32(re32);
+ pcre2_match_data_free_32(mdata32_1);
+ pcre2_match_data_free_32(mdata32_2);
+ pcre2_match_context_free_32(mcontext32);
+#endif
+
+ if (is_successful) {
+ successful++;
+ successful_row++;
+ printf(".");
+ if (successful_row >= 60) {
+ successful_row = 0;
+ printf("\n");
+ }
+ } else
+ successful_row = 0;
+
+ fflush(stdout);
+ current++;
+ }
+#ifdef SUPPORT_PCRE2_8
+ setstack8(NULL);
+#endif
+#ifdef SUPPORT_PCRE2_16
+ setstack16(NULL);
+#endif
+#ifdef SUPPORT_PCRE2_32
+ setstack32(NULL);
+#endif
+
+ if (total == successful) {
+ printf("\nAll JIT regression tests are successfully passed.\n");
+ return 0;
+ } else {
+ printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful);
+ return 1;
+ }
+}
+
+/* End of pcre2_jit_test.c */
diff --git a/thirdparty/pcre2/src/pcre2_maketables.c b/thirdparty/pcre2/src/pcre2_maketables.c
new file mode 100644
index 0000000000..2c7ae84d86
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_maketables.c
@@ -0,0 +1,157 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre2_maketables(), which builds
+character tables for PCRE2 in the current locale. The file is compiled on its
+own as part of the PCRE2 library. However, it is also included in the
+compilation of dftables.c, in which case the macro DFTABLES is defined. */
+
+#ifndef DFTABLES
+# ifdef HAVE_CONFIG_H
+# include "config.h"
+# endif
+# include "pcre2_internal.h"
+#endif
+
+
+
+/*************************************************
+* Create PCRE2 character tables *
+*************************************************/
+
+/* This function builds a set of character tables for use by PCRE2 and returns
+a pointer to them. They are build using the ctype functions, and consequently
+their contents will depend upon the current locale setting. When compiled as
+part of the library, the store is obtained via a general context malloc, if
+supplied, but when DFTABLES is defined (when compiling the dftables auxiliary
+program) malloc() is used, and the function has a different name so as not to
+clash with the prototype in pcre2.h.
+
+Arguments: none when DFTABLES is defined
+ else a PCRE2 general context or NULL
+Returns: pointer to the contiguous block of data
+*/
+
+#ifdef DFTABLES /* Included in freestanding dftables.c program */
+static const uint8_t *maketables(void)
+{
+uint8_t *yield = (uint8_t *)malloc(tables_length);
+
+#else /* Not DFTABLES, compiling the library */
+PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION
+pcre2_maketables(pcre2_general_context *gcontext)
+{
+uint8_t *yield = (uint8_t *)((gcontext != NULL)?
+ gcontext->memctl.malloc(tables_length, gcontext->memctl.memory_data) :
+ malloc(tables_length));
+#endif /* DFTABLES */
+
+int i;
+uint8_t *p;
+
+if (yield == NULL) return NULL;
+p = yield;
+
+/* First comes the lower casing table */
+
+for (i = 0; i < 256; i++) *p++ = tolower(i);
+
+/* Next the case-flipping table */
+
+for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
+
+/* Then the character class tables. Don't try to be clever and save effort on
+exclusive ones - in some locales things may be different.
+
+Note that the table for "space" includes everything "isspace" gives, including
+VT in the default locale. This makes it work for the POSIX class [:space:].
+From release 8.34 is is also correct for Perl space, because Perl added VT at
+release 5.18.
+
+Note also that it is possible for a character to be alnum or alpha without
+being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the
+fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must
+test for alnum specially. */
+
+memset(p, 0, cbit_length);
+for (i = 0; i < 256; i++)
+ {
+ if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7);
+ if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7);
+ if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7);
+ if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7);
+ if (i == '_') p[cbit_word + i/8] |= 1 << (i&7);
+ if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7);
+ if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
+ if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7);
+ if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7);
+ if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7);
+ if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7);
+ }
+p += cbit_length;
+
+/* Finally, the character type table. In this, we used to exclude VT from the
+white space chars, because Perl didn't recognize it as such for \s and for
+comments within regexes. However, Perl changed at release 5.18, so PCRE changed
+at release 8.34. */
+
+for (i = 0; i < 256; i++)
+ {
+ int x = 0;
+ if (isspace(i)) x += ctype_space;
+ if (isalpha(i)) x += ctype_letter;
+ if (isdigit(i)) x += ctype_digit;
+ if (isxdigit(i)) x += ctype_xdigit;
+ if (isalnum(i) || i == '_') x += ctype_word;
+
+ /* Note: strchr includes the terminating zero in the characters it considers.
+ In this instance, that is ok because we want binary zero to be flagged as a
+ meta-character, which in this sense is any character that terminates a run
+ of data characters. */
+
+ if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta;
+ *p++ = x;
+ }
+
+return yield;
+}
+
+/* End of pcre2_maketables.c */
diff --git a/thirdparty/pcre2/src/pcre2_match.c b/thirdparty/pcre2/src/pcre2_match.c
new file mode 100644
index 0000000000..78a9bacbc8
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_match.c
@@ -0,0 +1,7238 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK mb /* Block containing newline information */
+#define PSSTART start_subject /* Field containing processed string start */
+#define PSEND end_subject /* Field containing processed string end */
+
+#include "pcre2_internal.h"
+
+/* Masks for identifying the public options that are permitted at match time.
+*/
+
+#define PUBLIC_MATCH_OPTIONS \
+ (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
+ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
+ PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT)
+
+#define PUBLIC_JIT_MATCH_OPTIONS \
+ (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\
+ PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD)
+
+/* The mb->capture_last field uses the lower 16 bits for the last captured
+substring (which can never be greater than 65535) and a bit in the top half
+to mean "capture vector overflowed". This odd way of doing things was
+implemented when it was realized that preserving and restoring the overflow bit
+whenever the last capture number was saved/restored made for a neater
+interface, and doing it this way saved on (a) another variable, which would
+have increased the stack frame size (a big NO-NO in PCRE) and (b) another
+separate set of save/restore instructions. The following defines are used in
+implementing this. */
+
+#define CAPLMASK 0x0000ffff /* The bits used for last_capture */
+#define OVFLMASK 0xffff0000 /* The bits used for the overflow flag */
+#define OVFLBIT 0x00010000 /* The bit that is set for overflow */
+
+/* Bits for setting in mb->match_function_type to indicate two special types
+of call to match(). We do it this way to save on using another stack variable,
+as stack usage is to be discouraged. */
+
+#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */
+#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */
+
+/* Non-error returns from the match() function. Error returns are externally
+defined PCRE2_ERROR_xxx codes, which are all negative. */
+
+#define MATCH_MATCH 1
+#define MATCH_NOMATCH 0
+
+/* Special internal returns from the match() function. Make them sufficiently
+negative to avoid the external error codes. */
+
+#define MATCH_ACCEPT (-999)
+#define MATCH_KETRPOS (-998)
+#define MATCH_ONCE (-997)
+/* The next 5 must be kept together and in sequence so that a test that checks
+for any one of them can use a range. */
+#define MATCH_COMMIT (-996)
+#define MATCH_PRUNE (-995)
+#define MATCH_SKIP (-994)
+#define MATCH_SKIP_ARG (-993)
+#define MATCH_THEN (-992)
+#define MATCH_BACKTRACK_MAX MATCH_THEN
+#define MATCH_BACKTRACK_MIN MATCH_COMMIT
+
+/* Min and max values for the common repeats; for the maxima, 0 => infinity */
+
+static const char rep_min[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, };
+static const char rep_max[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, };
+
+/* Maximum number of ovector elements that can be saved on the system stack
+when processing OP_RECURSE in non-HEAP_MATCH_RECURSE mode. If the ovector is
+bigger, malloc() is used. This value should be a multiple of 3, because the
+ovector length is always a multiple of 3. */
+
+#define OP_RECURSE_STACK_SAVE_MAX 45
+
+
+
+/*************************************************
+* Match a back-reference *
+*************************************************/
+
+/* This function is called only when it is known that the offset lies within
+the offsets that have so far been used in the match. Note that in caseless
+UTF-8 mode, the number of subject bytes matched may be different to the number
+of reference bytes. (In theory this could also happen in UTF-16 mode, but it
+seems unlikely.)
+
+Arguments:
+ offset index into the offset vector
+ offset_top top of the used offset vector
+ eptr pointer into the subject
+ mb points to match block
+ caseless TRUE if caseless
+ lengthptr pointer for returning the length matched
+
+Returns: = 0 sucessful match; number of code units matched is set
+ < 0 no match
+ > 0 partial match
+*/
+
+static int
+match_ref(PCRE2_SIZE offset, PCRE2_SIZE offset_top, PCRE2_SPTR eptr,
+ match_block *mb, BOOL caseless, PCRE2_SIZE *lengthptr)
+{
+#if defined SUPPORT_UNICODE
+BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
+#endif
+
+PCRE2_SPTR p;
+PCRE2_SIZE length;
+PCRE2_SPTR eptr_start = eptr;
+
+/* Deal with an unset group. The default is no match, but there is an option to
+match an empty string. */
+
+if (offset >= offset_top || mb->ovector[offset] == PCRE2_UNSET)
+ {
+ if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
+ {
+ *lengthptr = 0;
+ return 0; /* Match */
+ }
+ else return -1; /* No match */
+ }
+
+/* Separate the caseless and UTF cases for speed. */
+
+p = mb->start_subject + mb->ovector[offset];
+length = mb->ovector[offset+1] - mb->ovector[offset];
+
+if (caseless)
+ {
+#if defined SUPPORT_UNICODE
+ if (utf)
+ {
+ /* Match characters up to the end of the reference. NOTE: the number of
+ code units matched may differ, because in UTF-8 there are some characters
+ whose upper and lower case versions code have different numbers of bytes.
+ For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65
+ (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
+ sequence of two of the latter. It is important, therefore, to check the
+ length along the reference, not along the subject (earlier code did this
+ wrong). */
+
+ PCRE2_SPTR endptr = p + length;
+ while (p < endptr)
+ {
+ uint32_t c, d;
+ const ucd_record *ur;
+ if (eptr >= mb->end_subject) return 1; /* Partial match */
+ GETCHARINC(c, eptr);
+ GETCHARINC(d, p);
+ ur = GET_UCD(d);
+ if (c != d && c != (uint32_t)((int)d + ur->other_case))
+ {
+ const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset;
+ for (;;)
+ {
+ if (c < *pp) return -1; /* No match */
+ if (c == *pp++) break;
+ }
+ }
+ }
+ }
+ else
+#endif
+
+ /* Not in UTF mode */
+
+ {
+ for (; length > 0; length--)
+ {
+ uint32_t cc, cp;
+ if (eptr >= mb->end_subject) return 1; /* Partial match */
+ cc = UCHAR21TEST(eptr);
+ cp = UCHAR21TEST(p);
+ if (TABLE_GET(cp, mb->lcc, cp) != TABLE_GET(cc, mb->lcc, cc))
+ return -1; /* No match */
+ p++;
+ eptr++;
+ }
+ }
+ }
+
+/* In the caseful case, we can just compare the code units, whether or not we
+are in UTF mode. */
+
+else
+ {
+ for (; length > 0; length--)
+ {
+ if (eptr >= mb->end_subject) return 1; /* Partial match */
+ if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1; /*No match */
+ }
+ }
+
+*lengthptr = eptr - eptr_start;
+return 0; /* Match */
+}
+
+
+
+/***************************************************************************
+****************************************************************************
+ RECURSION IN THE match() FUNCTION
+
+The match() function is highly recursive, though not every recursive call
+increases the recursion depth. Nevertheless, some regular expressions can cause
+it to recurse to a great depth. I was writing for Unix, so I just let it call
+itself recursively. This uses the stack for saving everything that has to be
+saved for a recursive call. On Unix, the stack can be large, and this works
+fine.
+
+It turns out that on some non-Unix-like systems there are problems with
+programs that use a lot of stack. (This despite the fact that every last chip
+has oodles of memory these days, and techniques for extending the stack have
+been known for decades.) So....
+
+There is a fudge, triggered by defining HEAP_MATCH_RECURSE, which avoids
+recursive calls by keeping local variables that need to be preserved in blocks
+of memory on the heap instead instead of on the stack. Macros are used to
+achieve this so that the actual code doesn't look very different to what it
+always used to.
+
+The original heap-recursive code used longjmp(). However, it seems that this
+can be very slow on some operating systems. Following a suggestion from Stan
+Switzer, the use of longjmp() has been abolished, at the cost of having to
+provide a unique number for each call to RMATCH. There is no way of generating
+a sequence of numbers at compile time in C. I have given them names, to make
+them stand out more clearly.
+
+Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
+FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
+tests. Furthermore, not using longjmp() means that local dynamic variables
+don't have indeterminate values; this has meant that the frame size can be
+reduced because the result can be "passed back" by straight setting of the
+variable instead of being passed in the frame.
+****************************************************************************
+***************************************************************************/
+
+/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
+below must be updated in sync. */
+
+enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
+ RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
+ RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
+ RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
+ RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
+ RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
+ RM61, RM62, RM63, RM64, RM65, RM66, RM67, RM68 };
+
+/* These versions of the macros use the stack, as normal. Note that the "rw"
+argument of RMATCH isn't actually used in this definition. */
+
+#ifndef HEAP_MATCH_RECURSE
+#define RMATCH(ra,rb,rc,rd,re,rw) \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
+#define RRETURN(ra) return ra
+#else
+
+/* These versions of the macros manage a private stack on the heap. Note that
+the "rd" argument of RMATCH isn't actually used in this definition. It's the mb
+argument of match(), which never changes. */
+
+#define RMATCH(ra,rb,rc,rd,re,rw)\
+ {\
+ heapframe *newframe = frame->Xnextframe;\
+ if (newframe == NULL)\
+ {\
+ newframe = (heapframe *)(mb->stack_memctl.malloc)\
+ (sizeof(heapframe), mb->stack_memctl.memory_data);\
+ if (newframe == NULL) RRETURN(PCRE2_ERROR_NOMEMORY);\
+ newframe->Xnextframe = NULL;\
+ frame->Xnextframe = newframe;\
+ }\
+ frame->Xwhere = rw;\
+ newframe->Xeptr = ra;\
+ newframe->Xecode = rb;\
+ newframe->Xmstart = mstart;\
+ newframe->Xoffset_top = rc;\
+ newframe->Xeptrb = re;\
+ newframe->Xrdepth = frame->Xrdepth + 1;\
+ newframe->Xprevframe = frame;\
+ frame = newframe;\
+ goto HEAP_RECURSE;\
+ L_##rw:;\
+ }
+
+#define RRETURN(ra)\
+ {\
+ heapframe *oldframe = frame;\
+ frame = oldframe->Xprevframe;\
+ if (frame != NULL)\
+ {\
+ rrc = ra;\
+ goto HEAP_RETURN;\
+ }\
+ return ra;\
+ }
+
+
+/* Structure for remembering the local variables in a private frame. Arrange it
+so as to minimize the number of holes. */
+
+typedef struct heapframe {
+ struct heapframe *Xprevframe;
+ struct heapframe *Xnextframe;
+
+#ifdef SUPPORT_UNICODE
+ PCRE2_SPTR Xcharptr;
+#endif
+ PCRE2_SPTR Xeptr;
+ PCRE2_SPTR Xecode;
+ PCRE2_SPTR Xmstart;
+ PCRE2_SPTR Xcallpat;
+ PCRE2_SPTR Xdata;
+ PCRE2_SPTR Xnext_ecode;
+ PCRE2_SPTR Xpp;
+ PCRE2_SPTR Xprev;
+ PCRE2_SPTR Xsaved_eptr;
+
+ eptrblock *Xeptrb;
+
+ PCRE2_SIZE Xlength;
+ PCRE2_SIZE Xoffset;
+ PCRE2_SIZE Xoffset_top;
+ PCRE2_SIZE Xsave_offset1, Xsave_offset2, Xsave_offset3;
+
+ uint32_t Xfc;
+ uint32_t Xnumber;
+ uint32_t Xrdepth;
+ uint32_t Xop;
+ uint32_t Xsave_capture_last;
+
+#ifdef SUPPORT_UNICODE
+ uint32_t Xprop_value;
+ int Xprop_type;
+ int Xprop_fail_result;
+ int Xoclength;
+#endif
+
+ int Xcodelink;
+ int Xctype;
+ int Xfi;
+ int Xmax;
+ int Xmin;
+ int Xwhere; /* Where to jump back to */
+
+ BOOL Xcondition;
+ BOOL Xcur_is_word;
+ BOOL Xprev_is_word;
+
+ eptrblock Xnewptrb;
+ recursion_info Xnew_recursive;
+
+#ifdef SUPPORT_UNICODE
+ PCRE2_UCHAR Xocchars[6];
+#endif
+} heapframe;
+
+#endif
+
+
+/***************************************************************************
+***************************************************************************/
+
+
+/* When HEAP_MATCH_RECURSE is not defined, the match() function implements
+backtrack points by calling itself recursively in all but one case. The one
+special case is when processing OP_RECURSE, which specifies recursion in the
+pattern. The entire ovector must be saved and restored while processing
+OP_RECURSE. If the ovector is small enough, instead of calling match()
+directly, op_recurse_ovecsave() is called. This function uses the system stack
+to save the ovector while calling match() to process the pattern recursion. */
+
+#ifndef HEAP_MATCH_RECURSE
+
+/* We need a prototype for match() because it is mutually recursive with
+op_recurse_ovecsave(). */
+
+static int
+match(PCRE2_SPTR eptr, PCRE2_SPTR ecode, PCRE2_SPTR mstart,
+ PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth);
+
+
+/*************************************************
+* Process OP_RECURSE, stacking ovector *
+*************************************************/
+
+/* When this function is called, mb->recursive has already been updated to
+point to a new recursion data block, and all its fields other than ovec_save
+have been set.
+
+This function exists so that the local vector variable ovecsave is no longer
+defined in the match() function, as it was in PCRE1. It is used only when there
+is recursion in the pattern, so it wastes a lot of stack to have it defined for
+every call of match(). We now use this function as an indirect way of calling
+match() only in the case when ovecsave is needed. (David Wheeler used to say
+"All problems in computer science can be solved by another level of
+indirection.")
+
+HOWEVER: when this file is compiled by gcc in an optimizing mode, because this
+function is called only once, and only from within match(), gcc will "inline"
+it - that is, move it inside match() - and this completely negates its reason
+for existence. Therefore, we mark it as non-inline when gcc is in use.
+
+Arguments:
+ eptr pointer to current character in subject
+ callpat the recursion point in the pattern
+ mstart pointer to the current match start position (can be modified
+ by encountering \K)
+ offset_top current top pointer (highest ovector offset used + 1)
+ mb pointer to "static" info block for the match
+ eptrb pointer to chain of blocks containing eptr at start of
+ brackets - for testing for empty matches
+ rdepth the recursion depth
+
+Returns: a match() return code
+*/
+
+static int
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+__attribute__ ((noinline))
+#endif
+op_recurse_ovecsave(PCRE2_SPTR eptr, PCRE2_SPTR callpat,
+ PCRE2_SPTR mstart, PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb,
+ uint32_t rdepth)
+{
+int rrc;
+BOOL cbegroup = *callpat >= OP_SBRA;
+recursion_info *new_recursive = mb->recursive;
+PCRE2_SIZE ovecsave[OP_RECURSE_STACK_SAVE_MAX];
+
+/* Save the ovector */
+
+new_recursive->ovec_save = ovecsave;
+memcpy(ovecsave, mb->ovector, mb->offset_end * sizeof(PCRE2_SIZE));
+
+/* Do the recursion. After processing each alternative, restore the ovector
+data and the last captured value. */
+
+do
+ {
+ if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP;
+ rrc = match(eptr, callpat + PRIV(OP_lengths)[*callpat], mstart, offset_top,
+ mb, eptrb, rdepth + 1);
+ memcpy(mb->ovector, new_recursive->ovec_save,
+ mb->offset_end * sizeof(PCRE2_SIZE));
+ mb->capture_last = new_recursive->saved_capture_last;
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) return rrc;
+
+ /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
+ recursion; they cause a NOMATCH for the entire recursion. These codes
+ are defined in a range that can be tested for. */
+
+ if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
+ return MATCH_NOMATCH;
+
+ /* Any return code other than NOMATCH is an error. Otherwise, advance to the
+ next alternative or to the end of the recursing subpattern. If there were
+ nested recursions, mb->recursive might be changed, so reset it before
+ looping. */
+
+ if (rrc != MATCH_NOMATCH) return rrc;
+ mb->recursive = new_recursive;
+ callpat += GET(callpat, 1);
+ }
+while (*callpat == OP_ALT); /* Loop for the alternatives */
+
+/* None of the alternatives matched. */
+
+return MATCH_NOMATCH;
+}
+#endif /* HEAP_MATCH_RECURSE */
+
+
+
+/*************************************************
+* Match from current position *
+*************************************************/
+
+/* This function is called recursively in many circumstances. Whenever it
+returns a negative (error) response, the outer incarnation must also return the
+same response. */
+
+/* These macros pack up tests that are used for partial matching, and which
+appear several times in the code. We set the "hit end" flag if the pointer is
+at the end of the subject and also past the earliest inspected character (i.e.
+something has been matched, even if not part of the actual matched string). For
+hard partial matching, we then return immediately. The second one is used when
+we already know we are past the end of the subject. */
+
+#define CHECK_PARTIAL()\
+ if (mb->partial != 0 && eptr >= mb->end_subject && \
+ eptr > mb->start_used_ptr) \
+ { \
+ mb->hitend = TRUE; \
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \
+ }
+
+#define SCHECK_PARTIAL()\
+ if (mb->partial != 0 && eptr > mb->start_used_ptr) \
+ { \
+ mb->hitend = TRUE; \
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \
+ }
+
+
+/* Performance note: It might be tempting to extract commonly used fields from
+the mb structure (e.g. utf, end_subject) into individual variables to improve
+performance. Tests using gcc on a SPARC disproved this; in the first case, it
+made performance worse.
+
+Arguments:
+ eptr pointer to current character in subject
+ ecode pointer to current position in compiled code
+ mstart pointer to the current match start position (can be modified
+ by encountering \K)
+ offset_top current top pointer (highest ovector offset used + 1)
+ mb pointer to "static" info block for the match
+ eptrb pointer to chain of blocks containing eptr at start of
+ brackets - for testing for empty matches
+ rdepth the recursion depth
+
+Returns: MATCH_MATCH if matched ) these values are >= 0
+ MATCH_NOMATCH if failed to match )
+ a negative MATCH_xxx value for PRUNE, SKIP, etc
+ a negative PCRE2_ERROR_xxx value if aborted by an error condition
+ (e.g. stopped by repeated call or recursion limit)
+*/
+
+static int
+match(PCRE2_SPTR eptr, PCRE2_SPTR ecode, PCRE2_SPTR mstart,
+ PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth)
+{
+/* These variables do not need to be preserved over recursion in this function,
+so they can be ordinary variables in all cases. Mark some of them with
+"register" because they are used a lot in loops. */
+
+int rrc; /* Returns from recursive calls */
+int i; /* Used for loops not involving calls to RMATCH() */
+uint32_t c; /* Character values not kept over RMATCH() calls */
+BOOL utf; /* Local copy of UTF flag for speed */
+
+BOOL minimize, possessive; /* Quantifier options */
+int condcode;
+
+/* When recursion is not being used, all "local" variables that have to be
+preserved over calls to RMATCH() are part of a "frame". We set up the top-level
+frame on the stack here; subsequent instantiations are obtained from the heap
+whenever RMATCH() does a "recursion". See the macro definitions above. Putting
+the top-level on the stack rather than malloc-ing them all gives a performance
+boost in many cases where there is not much "recursion". */
+
+#ifdef HEAP_MATCH_RECURSE
+heapframe *frame = (heapframe *)mb->match_frames_base;
+
+/* Copy in the original argument variables */
+
+frame->Xeptr = eptr;
+frame->Xecode = ecode;
+frame->Xmstart = mstart;
+frame->Xoffset_top = offset_top;
+frame->Xeptrb = eptrb;
+frame->Xrdepth = rdepth;
+
+/* This is where control jumps back to to effect "recursion" */
+
+HEAP_RECURSE:
+
+/* Macros make the argument variables come from the current frame */
+
+#define eptr frame->Xeptr
+#define ecode frame->Xecode
+#define mstart frame->Xmstart
+#define offset_top frame->Xoffset_top
+#define eptrb frame->Xeptrb
+#define rdepth frame->Xrdepth
+
+/* Ditto for the local variables */
+
+#ifdef SUPPORT_UNICODE
+#define charptr frame->Xcharptr
+#define prop_value frame->Xprop_value
+#define prop_type frame->Xprop_type
+#define prop_fail_result frame->Xprop_fail_result
+#define oclength frame->Xoclength
+#define occhars frame->Xocchars
+#endif
+
+
+#define callpat frame->Xcallpat
+#define codelink frame->Xcodelink
+#define data frame->Xdata
+#define next_ecode frame->Xnext_ecode
+#define pp frame->Xpp
+#define prev frame->Xprev
+#define saved_eptr frame->Xsaved_eptr
+
+#define new_recursive frame->Xnew_recursive
+
+#define ctype frame->Xctype
+#define fc frame->Xfc
+#define fi frame->Xfi
+#define length frame->Xlength
+#define max frame->Xmax
+#define min frame->Xmin
+#define number frame->Xnumber
+#define offset frame->Xoffset
+#define op frame->Xop
+#define save_capture_last frame->Xsave_capture_last
+#define save_offset1 frame->Xsave_offset1
+#define save_offset2 frame->Xsave_offset2
+#define save_offset3 frame->Xsave_offset3
+
+#define condition frame->Xcondition
+#define cur_is_word frame->Xcur_is_word
+#define prev_is_word frame->Xprev_is_word
+
+#define newptrb frame->Xnewptrb
+
+/* When normal stack-based recursion is being used for match(), local variables
+are allocated on the stack and get preserved during recursion in the usual way.
+In this environment, fi and i, and fc and c, can be the same variables. */
+
+#else /* HEAP_MATCH_RECURSE not defined */
+#define fi i
+#define fc c
+
+/* Many of the following variables are used only in small blocks of the code.
+My normal style of coding would have declared them within each of those blocks.
+However, in order to accommodate the version of this code that uses an external
+"stack" implemented on the heap, it is easier to declare them all here, so the
+declarations can be cut out in a block. The only declarations within blocks
+below are for variables that do not have to be preserved over a recursive call
+to RMATCH(). */
+
+#ifdef SUPPORT_UNICODE
+PCRE2_SPTR charptr;
+#endif
+PCRE2_SPTR callpat;
+PCRE2_SPTR data;
+PCRE2_SPTR next_ecode;
+PCRE2_SPTR pp;
+PCRE2_SPTR prev;
+PCRE2_SPTR saved_eptr;
+
+PCRE2_SIZE length;
+PCRE2_SIZE offset;
+PCRE2_SIZE save_offset1, save_offset2, save_offset3;
+
+uint32_t number;
+uint32_t op;
+uint32_t save_capture_last;
+
+#ifdef SUPPORT_UNICODE
+uint32_t prop_value;
+int prop_type;
+int prop_fail_result;
+int oclength;
+PCRE2_UCHAR occhars[6];
+#endif
+
+int codelink;
+int ctype;
+int max;
+int min;
+
+BOOL condition;
+BOOL cur_is_word;
+BOOL prev_is_word;
+
+eptrblock newptrb;
+recursion_info new_recursive;
+#endif /* HEAP_MATCH_RECURSE not defined */
+
+/* To save space on the stack and in the heap frame, I have doubled up on some
+of the local variables that are used only in localised parts of the code, but
+still need to be preserved over recursive calls of match(). These macros define
+the alternative names that are used. */
+
+#define allow_zero cur_is_word
+#define caseless cur_is_word
+#define cbegroup condition
+#define code_offset codelink
+#define condassert condition
+#define foc number
+#define matched_once prev_is_word
+#define save_mark data
+
+/* These statements are here to stop the compiler complaining about unitialized
+variables. */
+
+#ifdef SUPPORT_UNICODE
+prop_value = 0;
+prop_fail_result = 0;
+#endif
+
+
+/* This label is used for tail recursion, which is used in a few cases even
+when HEAP_MATCH_RECURSE is not defined, in order to reduce the amount of stack
+that is used. Thanks to Ian Taylor for noticing this possibility and sending
+the original patch. */
+
+TAIL_RECURSE:
+
+/* OK, now we can get on with the real code of the function. Recursive calls
+are specified by the macro RMATCH and RRETURN is used to return. When
+HEAP_MATCH_RECURSE is *not* defined, these just turn into a recursive call to
+match() and a "return", respectively. However, RMATCH isn't like a function
+call because it's quite a complicated macro. It has to be used in one
+particular way. This shouldn't, however, impact performance when true recursion
+is being used. */
+
+#ifdef SUPPORT_UNICODE
+utf = (mb->poptions & PCRE2_UTF) != 0;
+#else
+utf = FALSE;
+#endif
+
+/* First check that we haven't called match() too many times, or that we
+haven't exceeded the recursive call limit. */
+
+if (mb->match_call_count++ >= mb->match_limit) RRETURN(PCRE2_ERROR_MATCHLIMIT);
+if (rdepth >= mb->match_limit_recursion) RRETURN(PCRE2_ERROR_RECURSIONLIMIT);
+
+/* At the start of a group with an unlimited repeat that may match an empty
+string, the variable mb->match_function_type contains the MATCH_CBEGROUP bit.
+It is done this way to save having to use another function argument, which
+would take up space on the stack. See also MATCH_CONDASSERT below.
+
+When MATCH_CBEGROUP is set, add the current subject pointer to the chain of
+such remembered pointers, to be checked when we hit the closing ket, in order
+to break infinite loops that match no characters. When match() is called in
+other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must
+NOT be used with tail recursion, because the memory block that is used is on
+the stack, so a new one may be required for each match(). */
+
+if ((mb->match_function_type & MATCH_CBEGROUP) != 0)
+ {
+ newptrb.epb_saved_eptr = eptr;
+ newptrb.epb_prev = eptrb;
+ eptrb = &newptrb;
+ mb->match_function_type &= ~MATCH_CBEGROUP;
+ }
+
+/* Now, at last, we can start processing the opcodes. */
+
+for (;;)
+ {
+ minimize = possessive = FALSE;
+ op = *ecode;
+
+ switch(op)
+ {
+ case OP_MARK:
+ mb->nomatch_mark = ecode + 2;
+ mb->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb,
+ eptrb, RM55);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ mb->mark == NULL) mb->mark = ecode + 2;
+
+ /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
+ argument, and we must check whether that argument matches this MARK's
+ argument. It is passed back in mb->start_match_ptr (an overloading of that
+ variable). If it does match, we reset that variable to the current subject
+ position and return MATCH_SKIP. Otherwise, pass back the return code
+ unaltered. */
+
+ else if (rrc == MATCH_SKIP_ARG &&
+ PRIV(strcmp)(ecode + 2, mb->start_match_ptr) == 0)
+ {
+ mb->start_match_ptr = eptr;
+ RRETURN(MATCH_SKIP);
+ }
+ RRETURN(rrc);
+
+ case OP_FAIL:
+ RRETURN(MATCH_NOMATCH);
+
+ case OP_COMMIT:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
+ eptrb, RM52);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ RRETURN(MATCH_COMMIT);
+
+ case OP_PRUNE:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
+ eptrb, RM51);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ RRETURN(MATCH_PRUNE);
+
+ case OP_PRUNE_ARG:
+ mb->nomatch_mark = ecode + 2;
+ mb->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb,
+ eptrb, RM56);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ mb->mark == NULL) mb->mark = ecode + 2;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ RRETURN(MATCH_PRUNE);
+
+ case OP_SKIP:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
+ eptrb, RM53);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->start_match_ptr = eptr; /* Pass back current position */
+ RRETURN(MATCH_SKIP);
+
+ /* Note that, for Perl compatibility, SKIP with an argument does NOT set
+ nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
+ not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
+ that failed and any that precede it (either they also failed, or were not
+ triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
+ SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg
+ set to the count of the one that failed. */
+
+ case OP_SKIP_ARG:
+ mb->skip_arg_count++;
+ if (mb->skip_arg_count <= mb->ignore_skip_arg)
+ {
+ ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
+ break;
+ }
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb,
+ eptrb, RM57);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+
+ /* Pass back the current skip name by overloading mb->start_match_ptr and
+ returning the special MATCH_SKIP_ARG return code. This will either be
+ caught by a matching MARK, or get to the top, where it causes a rematch
+ with mb->ignore_skip_arg set to the value of mb->skip_arg_count. */
+
+ mb->start_match_ptr = ecode + 2;
+ RRETURN(MATCH_SKIP_ARG);
+
+ /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
+ the branch in which it occurs can be determined. Overload the start of
+ match pointer to do this. */
+
+ case OP_THEN:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
+ eptrb, RM54);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->start_match_ptr = ecode;
+ RRETURN(MATCH_THEN);
+
+ case OP_THEN_ARG:
+ mb->nomatch_mark = ecode + 2;
+ mb->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
+ mb, eptrb, RM58);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ mb->mark == NULL) mb->mark = ecode + 2;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->start_match_ptr = ecode;
+ RRETURN(MATCH_THEN);
+
+ /* Handle an atomic group that does not contain any capturing parentheses.
+ This can be handled like an assertion. Prior to 8.13, all atomic groups
+ were handled this way. In 8.13, the code was changed as below for ONCE, so
+ that backups pass through the group and thereby reset captured values.
+ However, this uses a lot more stack, so in 8.20, atomic groups that do not
+ contain any captures generate OP_ONCE_NC, which can be handled in the old,
+ less stack intensive way.
+
+ Check the alternative branches in turn - the matching won't pass the KET
+ for this kind of subpattern. If any one branch matches, we carry on as at
+ the end of a normal bracket, leaving the subject pointer, but resetting
+ the start-of-match value in case it was changed by \K. */
+
+ case OP_ONCE_NC:
+ prev = ecode;
+ saved_eptr = eptr;
+ save_mark = mb->mark;
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM64);
+ if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */
+ {
+ mstart = mb->start_match_ptr;
+ break;
+ }
+ if (rrc == MATCH_THEN)
+ {
+ next_ecode = ecode + GET(ecode,1);
+ if (mb->start_match_ptr < next_ecode &&
+ (*ecode == OP_ALT || *next_ecode == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode,1);
+ mb->mark = save_mark;
+ }
+ while (*ecode == OP_ALT);
+
+ /* If hit the end of the group (which could be repeated), fail */
+
+ if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+
+ /* Continue as from after the group, updating the offsets high water
+ mark, since extracts may have been taken. */
+
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+
+ offset_top = mb->end_offset_top;
+ eptr = mb->end_match_ptr;
+
+ /* For a non-repeating ket, just continue at this level. This also
+ happens for a repeating ket if no characters were matched in the group.
+ This is the forcible breaking of infinite loops as implemented in Perl
+ 5.005. */
+
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ ecode += 1+LINK_SIZE;
+ break;
+ }
+
+ /* The repeating kets try the rest of the pattern or restart from the
+ preceding bracket, in the appropriate order. The second "call" of match()
+ uses tail recursion, to avoid using another stack frame. */
+
+ if (*ecode == OP_KETRMIN)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM65);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode = prev;
+ goto TAIL_RECURSE;
+ }
+ else /* OP_KETRMAX */
+ {
+ RMATCH(eptr, prev, offset_top, mb, eptrb, RM66);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+ /* Control never gets here */
+
+ /* Handle a capturing bracket, other than those that are possessive with an
+ unlimited repeat. If there is space in the offset vector, save the current
+ subject position in the working slot at the top of the vector. We mustn't
+ change the current values of the data slot, because they may be set from a
+ previous iteration of this group, and be referred to by a reference inside
+ the group. A failure to match might occur after the group has succeeded,
+ if something later on doesn't match. For this reason, we need to restore
+ the working value and also the values of the final offsets, in case they
+ were set by a previous iteration of the same bracket.
+
+ If there isn't enough space in the offset vector, treat this as if it were
+ a non-capturing bracket. Don't worry about setting the flag for the error
+ case here; that is handled in the code for KET. */
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ number = GET2(ecode, 1+LINK_SIZE);
+ offset = number << 1;
+
+ if (offset < mb->offset_max)
+ {
+ save_offset1 = mb->ovector[offset];
+ save_offset2 = mb->ovector[offset+1];
+ save_offset3 = mb->ovector[mb->offset_end - number];
+ save_capture_last = mb->capture_last;
+ save_mark = mb->mark;
+
+ mb->ovector[mb->offset_end - number] = eptr - mb->start_subject;
+
+ for (;;)
+ {
+ if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
+ eptrb, RM1);
+ if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */
+
+ /* If we backed up to a THEN, check whether it is within the current
+ branch by comparing the address of the THEN that is passed back with
+ the end of the branch. If it is within the current branch, and the
+ branch is one of two or more alternatives (it either starts or ends
+ with OP_ALT), we have reached the limit of THEN's action, so convert
+ the return code to NOMATCH, which will cause normal backtracking to
+ happen from now on. Otherwise, THEN is passed back to an outer
+ alternative. This implements Perl's treatment of parenthesized groups,
+ where a group not containing | does not affect the current alternative,
+ that is, (X) is NOT the same as (X|(*F)). */
+
+ if (rrc == MATCH_THEN)
+ {
+ next_ecode = ecode + GET(ecode,1);
+ if (mb->start_match_ptr < next_ecode &&
+ (*ecode == OP_ALT || *next_ecode == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ /* Anything other than NOMATCH is passed back. */
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ mb->mark = save_mark;
+ if (*ecode != OP_ALT) break;
+ }
+
+ mb->ovector[offset] = save_offset1;
+ mb->ovector[offset+1] = save_offset2;
+ mb->ovector[mb->offset_end - number] = save_offset3;
+
+ /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
+
+ RRETURN(rrc);
+ }
+
+ /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
+ as a non-capturing bracket. */
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ /* Non-capturing or atomic group, except for possessive with unlimited
+ repeat and ONCE group with no captures. Loop for all the alternatives.
+
+ When we get to the final alternative within the brackets, we used to return
+ the result of a recursive call to match() whatever happened so it was
+ possible to reduce stack usage by turning this into a tail recursion,
+ except in the case of a possibly empty group. However, now that there is
+ the possiblity of (*THEN) occurring in the final alternative, this
+ optimization is no longer always possible.
+
+ We can optimize if we know there are no (*THEN)s in the pattern; at present
+ this is the best that can be done.
+
+ MATCH_ONCE is returned when the end of an atomic group is successfully
+ reached, but subsequent matching fails. It passes back up the tree (causing
+ captured values to be reset) until the original atomic group level is
+ reached. This is tested by comparing mb->once_target with the start of the
+ group. At this point, the return is converted into MATCH_NOMATCH so that
+ previous backup points can be taken. */
+
+ case OP_ONCE:
+ case OP_BRA:
+ case OP_SBRA:
+
+ for (;;)
+ {
+ if (op >= OP_SBRA || op == OP_ONCE)
+ mb->match_function_type |= MATCH_CBEGROUP;
+
+ /* If this is not a possibly empty group, and there are no (*THEN)s in
+ the pattern, and this is the final alternative, optimize as described
+ above. */
+
+ else if (!mb->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
+ {
+ ecode += PRIV(OP_lengths)[*ecode];
+ goto TAIL_RECURSE;
+ }
+
+ /* In all other cases, we have to make another call to match(). */
+
+ save_mark = mb->mark;
+ save_capture_last = mb->capture_last;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, eptrb,
+ RM2);
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next_ecode = ecode + GET(ecode,1);
+ if (mb->start_match_ptr < next_ecode &&
+ (*ecode == OP_ALT || *next_ecode == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH)
+ {
+ if (rrc == MATCH_ONCE)
+ {
+ PCRE2_SPTR scode = ecode;
+ if (*scode != OP_ONCE) /* If not at start, find it */
+ {
+ while (*scode == OP_ALT) scode += GET(scode, 1);
+ scode -= GET(scode, 1);
+ }
+ if (mb->once_target == scode) rrc = MATCH_NOMATCH;
+ }
+ RRETURN(rrc);
+ }
+ ecode += GET(ecode, 1);
+ mb->mark = save_mark;
+ if (*ecode != OP_ALT) break;
+ mb->capture_last = save_capture_last;
+ }
+
+ RRETURN(MATCH_NOMATCH);
+
+ /* Handle possessive capturing brackets with an unlimited repeat. We come
+ here from BRAZERO with allow_zero set TRUE. The ovector values are
+ handled similarly to the normal case above. However, the matching is
+ different. The end of these brackets will always be OP_KETRPOS, which
+ returns MATCH_KETRPOS without going further in the pattern. By this means
+ we can handle the group by iteration rather than recursion, thereby
+ reducing the amount of stack needed. If the ovector is too small for
+ capturing, treat as non-capturing. */
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_CAPTURE:
+ number = GET2(ecode, 1+LINK_SIZE);
+ offset = number << 1;
+ if (offset >= mb->offset_max) goto POSSESSIVE_NON_CAPTURE;
+
+ matched_once = FALSE;
+ code_offset = (int)(ecode - mb->start_code);
+
+ save_offset1 = mb->ovector[offset];
+ save_offset2 = mb->ovector[offset+1];
+ save_offset3 = mb->ovector[mb->offset_end - number];
+ save_capture_last = mb->capture_last;
+
+ /* Each time round the loop, save the current subject position for use
+ when the group matches. For MATCH_MATCH, the group has matched, so we
+ restart it with a new subject starting position, remembering that we had
+ at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
+ usual. If we haven't matched any alternatives in any iteration, check to
+ see if a previous iteration matched. If so, the group has matched;
+ continue from afterwards. Otherwise it has failed; restore the previous
+ capture values before returning NOMATCH. */
+
+ for (;;)
+ {
+ mb->ovector[mb->offset_end - number] = eptr - mb->start_subject;
+ if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
+ eptrb, RM63);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = mb->end_offset_top;
+ ecode = mb->start_code + code_offset;
+ save_capture_last = mb->capture_last;
+ matched_once = TRUE;
+ mstart = mb->start_match_ptr; /* In case \K changed it */
+ if (eptr == mb->end_match_ptr) /* Matched an empty string */
+ {
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+ break;
+ }
+ eptr = mb->end_match_ptr;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next_ecode = ecode + GET(ecode,1);
+ if (mb->start_match_ptr < next_ecode &&
+ (*ecode == OP_ALT || *next_ecode == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
+ }
+
+ if (!matched_once)
+ {
+ mb->ovector[offset] = save_offset1;
+ mb->ovector[offset+1] = save_offset2;
+ mb->ovector[mb->offset_end - number] = save_offset3;
+ }
+
+ if (allow_zero || matched_once)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
+ RRETURN(MATCH_NOMATCH);
+
+ /* Non-capturing possessive bracket with unlimited repeat. We come here
+ from BRAZERO with allow_zero = TRUE. The code is similar to the above,
+ without the capturing complication. It is written out separately for speed
+ and cleanliness. */
+
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_NON_CAPTURE:
+ matched_once = FALSE;
+ code_offset = (int)(ecode - mb->start_code);
+ save_capture_last = mb->capture_last;
+
+ for (;;)
+ {
+ if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
+ eptrb, RM48);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = mb->end_offset_top;
+ ecode = mb->start_code + code_offset;
+ matched_once = TRUE;
+ mstart = mb->start_match_ptr; /* In case \K reset it */
+ if (eptr == mb->end_match_ptr) /* Matched an empty string */
+ {
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+ break;
+ }
+ eptr = mb->end_match_ptr;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next_ecode = ecode + GET(ecode,1);
+ if (mb->start_match_ptr < next_ecode &&
+ (*ecode == OP_ALT || *next_ecode == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
+ mb->capture_last = save_capture_last;
+ }
+
+ if (matched_once || allow_zero)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
+ RRETURN(MATCH_NOMATCH);
+
+ /* Control never reaches here. */
+
+ /* Conditional group: compilation checked that there are no more than two
+ branches. If the condition is false, skipping the first branch takes us
+ past the end of the item if there is only one branch, but that's exactly
+ what we want. */
+
+ case OP_COND:
+ case OP_SCOND:
+
+ /* The variable codelink will be added to ecode when the condition is
+ false, to get to the second branch. Setting it to the offset to the ALT
+ or KET, then incrementing ecode achieves this effect. We now have ecode
+ pointing to the condition or callout. */
+
+ codelink = GET(ecode, 1); /* Offset to the second branch */
+ ecode += 1 + LINK_SIZE; /* From this opcode */
+
+ /* Because of the way auto-callout works during compile, a callout item is
+ inserted between OP_COND and an assertion condition. */
+
+ if (*ecode == OP_CALLOUT || *ecode == OP_CALLOUT_STR)
+ {
+ unsigned int callout_length = (*ecode == OP_CALLOUT)
+ ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE);
+
+ if (mb->callout != NULL)
+ {
+ pcre2_callout_block cb;
+ cb.version = 1;
+ cb.capture_top = (uint32_t)offset_top/2;
+ cb.capture_last = mb->capture_last & CAPLMASK;
+ cb.offset_vector = mb->ovector;
+ cb.mark = mb->nomatch_mark;
+ cb.subject = mb->start_subject;
+ cb.subject_length = (PCRE2_SIZE)(mb->end_subject - mb->start_subject);
+ cb.start_match = (PCRE2_SIZE)(mstart - mb->start_subject);
+ cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject);
+ cb.pattern_position = GET(ecode, 1);
+ cb.next_item_length = GET(ecode, 1 + LINK_SIZE);
+
+ if (*ecode == OP_CALLOUT)
+ {
+ cb.callout_number = ecode[1 + 2*LINK_SIZE];
+ cb.callout_string_offset = 0;
+ cb.callout_string = NULL;
+ cb.callout_string_length = 0;
+ }
+ else
+ {
+ cb.callout_number = 0;
+ cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE);
+ cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1;
+ cb.callout_string_length =
+ callout_length - (1 + 4*LINK_SIZE) - 2;
+ }
+
+ if ((rrc = mb->callout(&cb, mb->callout_data)) > 0)
+ RRETURN(MATCH_NOMATCH);
+ if (rrc < 0) RRETURN(rrc);
+ }
+
+ /* Advance ecode past the callout, so it now points to the condition. We
+ must adjust codelink so that the value of ecode+codelink is unchanged. */
+
+ ecode += callout_length;
+ codelink -= callout_length;
+ }
+
+ /* Test the various possible conditions */
+
+ condition = FALSE;
+ switch(condcode = *ecode)
+ {
+ case OP_RREF: /* Numbered group recursion test */
+ if (mb->recursive != NULL) /* Not recursing => FALSE */
+ {
+ uint32_t recno = GET2(ecode, 1); /* Recursion group number*/
+ condition = (recno == RREF_ANY || recno == mb->recursive->group_num);
+ }
+ break;
+
+ case OP_DNRREF: /* Duplicate named group recursion test */
+ if (mb->recursive != NULL)
+ {
+ int count = GET2(ecode, 1 + IMM2_SIZE);
+ PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size;
+ while (count-- > 0)
+ {
+ uint32_t recno = GET2(slot, 0);
+ condition = recno == mb->recursive->group_num;
+ if (condition) break;
+ slot += mb->name_entry_size;
+ }
+ }
+ break;
+
+ case OP_CREF: /* Numbered group used test */
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
+ condition = offset < offset_top &&
+ mb->ovector[offset] != PCRE2_UNSET;
+ break;
+
+ case OP_DNCREF: /* Duplicate named group used test */
+ {
+ int count = GET2(ecode, 1 + IMM2_SIZE);
+ PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size;
+ while (count-- > 0)
+ {
+ offset = GET2(slot, 0) << 1;
+ condition = offset < offset_top &&
+ mb->ovector[offset] != PCRE2_UNSET;
+ if (condition) break;
+ slot += mb->name_entry_size;
+ }
+ }
+ break;
+
+ case OP_FALSE:
+ case OP_FAIL: /* The assertion (?!) becomes OP_FAIL */
+ break;
+
+ case OP_TRUE:
+ condition = TRUE;
+ break;
+
+ /* The condition is an assertion. Call match() to evaluate it - setting
+ the MATCH_CONDASSERT bit in mb->match_function_type causes it to stop at
+ the end of an assertion. */
+
+ default:
+ mb->match_function_type |= MATCH_CONDASSERT;
+ RMATCH(eptr, ecode, offset_top, mb, NULL, RM3);
+ if (rrc == MATCH_MATCH)
+ {
+ if (mb->end_offset_top > offset_top)
+ offset_top = mb->end_offset_top; /* Captures may have happened */
+ condition = TRUE;
+
+ /* Advance ecode past the assertion to the start of the first branch,
+ but adjust it so that the general choosing code below works. If the
+ assertion has a quantifier that allows zero repeats we must skip over
+ the BRAZERO. This is a lunatic thing to do, but somebody did! */
+
+ if (*ecode == OP_BRAZERO) ecode++;
+ ecode += GET(ecode, 1);
+ while (*ecode == OP_ALT) ecode += GET(ecode, 1);
+ ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
+ }
+
+ /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
+ assertion; it is therefore treated as NOMATCH. Any other return is an
+ error. */
+
+ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
+ {
+ RRETURN(rrc); /* Need braces because of following else */
+ }
+ break;
+ }
+
+ /* Choose branch according to the condition */
+
+ ecode += condition? PRIV(OP_lengths)[condcode] : codelink;
+
+ /* We are now at the branch that is to be obeyed. As there is only one, we
+ can use tail recursion to avoid using another stack frame, except when
+ there is unlimited repeat of a possibly empty group. In the latter case, a
+ recursive call to match() is always required, unless the second alternative
+ doesn't exist, in which case we can just plough on. Note that, for
+ compatibility with Perl, the | in a conditional group is NOT treated as
+ creating two alternatives. If a THEN is encountered in the branch, it
+ propagates out to the enclosing alternative (unless nested in a deeper set
+ of alternatives, of course). */
+
+ if (condition || ecode[-(1+LINK_SIZE)] == OP_ALT)
+ {
+ if (op != OP_SCOND)
+ {
+ goto TAIL_RECURSE;
+ }
+
+ mb->match_function_type |= MATCH_CBEGROUP;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM49);
+ RRETURN(rrc);
+ }
+
+ /* Condition false & no alternative; continue after the group. */
+
+ else
+ {
+ }
+ break;
+
+
+ /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
+ to close any currently open capturing brackets. */
+
+ case OP_CLOSE:
+ number = GET2(ecode, 1); /* Must be less than 65536 */
+ offset = number << 1;
+ mb->capture_last = (mb->capture_last & OVFLMASK) | number;
+ if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else
+ {
+ mb->ovector[offset] =
+ mb->ovector[mb->offset_end - number];
+ mb->ovector[offset+1] = eptr - mb->start_subject;
+
+ /* If this group is at or above the current highwater mark, ensure that
+ any groups between the current high water mark and this group are marked
+ unset and then update the high water mark. */
+
+ if (offset >= offset_top)
+ {
+ PCRE2_SIZE *iptr = mb->ovector + offset_top;
+ PCRE2_SIZE *iend = mb->ovector + offset;
+ while (iptr < iend) *iptr++ = PCRE2_UNSET;
+ offset_top = offset + 2;
+ }
+ }
+ ecode += 1 + IMM2_SIZE;
+ break;
+
+
+ /* End of the pattern, either real or forced. In an assertion ACCEPT,
+ update the last used pointer. */
+
+ case OP_ASSERT_ACCEPT:
+ if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
+
+ case OP_ACCEPT:
+ case OP_END:
+
+ /* If we have matched an empty string, fail if not in an assertion and not
+ in a recursion if either PCRE2_NOTEMPTY is set, or if PCRE2_NOTEMPTY_ATSTART
+ is set and we have matched at the start of the subject. In both cases,
+ backtracking will then try other alternatives, if any. */
+
+ if (eptr == mstart && op != OP_ASSERT_ACCEPT &&
+ mb->recursive == NULL &&
+ ((mb->moptions & PCRE2_NOTEMPTY) != 0 ||
+ ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 &&
+ mstart == mb->start_subject + mb->start_offset)))
+ RRETURN(MATCH_NOMATCH);
+
+ /* Otherwise, we have a match. */
+
+ mb->end_match_ptr = eptr; /* Record where we ended */
+ mb->end_offset_top = offset_top; /* and how many extracts were taken */
+ mb->start_match_ptr = mstart; /* and the start (\K can modify) */
+
+ /* For some reason, the macros don't work properly if an expression is
+ given as the argument to RRETURN when the heap is in use. */
+
+ rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
+ RRETURN(rrc);
+
+ /* Assertion brackets. Check the alternative branches in turn - the
+ matching won't pass the KET for an assertion. If any one branch matches,
+ the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
+ start of each branch to move the current point backwards, so the code at
+ this level is identical to the lookahead case. When the assertion is part
+ of a condition, we want to return immediately afterwards. The caller of
+ this incarnation of the match() function will have set MATCH_CONDASSERT in
+ mb->match_function type, and one of these opcodes will be the first opcode
+ that is processed. We use a local variable that is preserved over calls to
+ match() to remember this case. */
+
+ case OP_ASSERT:
+ case OP_ASSERTBACK:
+ save_mark = mb->mark;
+ if ((mb->match_function_type & MATCH_CONDASSERT) != 0)
+ {
+ condassert = TRUE;
+ mb->match_function_type &= ~MATCH_CONDASSERT;
+ }
+ else condassert = FALSE;
+
+ /* Loop for each branch */
+
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM4);
+
+ /* A match means that the assertion is true; break out of the loop
+ that matches its alternatives. */
+
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
+ {
+ mstart = mb->start_match_ptr; /* In case \K reset it */
+ break;
+ }
+
+ /* If not matched, restore the previous mark setting. */
+
+ mb->mark = save_mark;
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next_ecode = ecode + GET(ecode,1);
+ if (mb->start_match_ptr < next_ecode &&
+ (*ecode == OP_ALT || *next_ecode == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ /* Anything other than NOMATCH causes the entire assertion to fail,
+ passing back the return code. This includes COMMIT, SKIP, PRUNE and an
+ uncaptured THEN, which means they take their normal effect. This
+ consistent approach does not always have exactly the same effect as in
+ Perl. */
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode, 1);
+ }
+ while (*ecode == OP_ALT); /* Continue for next alternative */
+
+ /* If we have tried all the alternative branches, the assertion has
+ failed. If not, we broke out after a match. */
+
+ if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
+
+ /* If checking an assertion for a condition, return MATCH_MATCH. */
+
+ if (condassert) RRETURN(MATCH_MATCH);
+
+ /* Continue from after a successful assertion, updating the offsets high
+ water mark, since extracts may have been taken during the assertion. */
+
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ ecode += 1 + LINK_SIZE;
+ offset_top = mb->end_offset_top;
+ continue;
+
+ /* Negative assertion: all branches must fail to match for the assertion to
+ succeed. */
+
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK_NOT:
+ save_mark = mb->mark;
+ if ((mb->match_function_type & MATCH_CONDASSERT) != 0)
+ {
+ condassert = TRUE;
+ mb->match_function_type &= ~MATCH_CONDASSERT;
+ }
+ else condassert = FALSE;
+
+ /* Loop for each alternative branch. */
+
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM5);
+ mb->mark = save_mark; /* Always restore the mark setting */
+
+ switch(rrc)
+ {
+ case MATCH_MATCH: /* A successful match means */
+ case MATCH_ACCEPT: /* the assertion has failed. */
+ RRETURN(MATCH_NOMATCH);
+
+ case MATCH_NOMATCH: /* Carry on with next branch */
+ break;
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ case MATCH_THEN:
+ next_ecode = ecode + GET(ecode,1);
+ if (mb->start_match_ptr < next_ecode &&
+ (*ecode == OP_ALT || *next_ecode == OP_ALT))
+ {
+ rrc = MATCH_NOMATCH;
+ break;
+ }
+ /* Otherwise fall through. */
+
+ /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole
+ assertion to fail to match, without considering any more alternatives.
+ Failing to match means the assertion is true. This is a consistent
+ approach, but does not always have the same effect as in Perl. */
+
+ case MATCH_COMMIT:
+ case MATCH_SKIP:
+ case MATCH_SKIP_ARG:
+ case MATCH_PRUNE:
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ goto NEG_ASSERT_TRUE; /* Break out of alternation loop */
+
+ /* Anything else is an error */
+
+ default:
+ RRETURN(rrc);
+ }
+
+ /* Continue with next branch */
+
+ ecode += GET(ecode,1);
+ }
+ while (*ecode == OP_ALT);
+
+ /* All branches in the assertion failed to match. */
+
+ NEG_ASSERT_TRUE:
+ if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
+ ecode += 1 + LINK_SIZE; /* Continue with current branch */
+ continue;
+
+ /* Move the subject pointer back. This occurs only at the start of
+ each branch of a lookbehind assertion. If we are too close to the start to
+ move back, this match function fails. When working with UTF-8 we move
+ back a number of characters, not bytes. */
+
+ case OP_REVERSE:
+ i = GET(ecode, 1);
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ while (i-- > 0)
+ {
+ if (eptr <= mb->start_subject) RRETURN(MATCH_NOMATCH);
+ eptr--;
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+
+ /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
+
+ {
+ if (i > eptr - mb->start_subject) RRETURN(MATCH_NOMATCH);
+ eptr -= i;
+ }
+
+ /* Save the earliest consulted character, then skip to next op code */
+
+ if (eptr < mb->start_used_ptr) mb->start_used_ptr = eptr;
+ ecode += 1 + LINK_SIZE;
+ break;
+
+ /* The callout item calls an external function, if one is provided, passing
+ details of the match so far. This is mainly for debugging, though the
+ function is able to force a failure. */
+
+ case OP_CALLOUT:
+ case OP_CALLOUT_STR:
+ {
+ unsigned int callout_length = (*ecode == OP_CALLOUT)
+ ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE);
+
+ if (mb->callout != NULL)
+ {
+ pcre2_callout_block cb;
+ cb.version = 1;
+ cb.callout_number = ecode[LINK_SIZE + 1];
+ cb.capture_top = (uint32_t)offset_top/2;
+ cb.capture_last = mb->capture_last & CAPLMASK;
+ cb.offset_vector = mb->ovector;
+ cb.mark = mb->nomatch_mark;
+ cb.subject = mb->start_subject;
+ cb.subject_length = (PCRE2_SIZE)(mb->end_subject - mb->start_subject);
+ cb.start_match = (PCRE2_SIZE)(mstart - mb->start_subject);
+ cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject);
+ cb.pattern_position = GET(ecode, 1);
+ cb.next_item_length = GET(ecode, 1 + LINK_SIZE);
+
+ if (*ecode == OP_CALLOUT)
+ {
+ cb.callout_number = ecode[1 + 2*LINK_SIZE];
+ cb.callout_string_offset = 0;
+ cb.callout_string = NULL;
+ cb.callout_string_length = 0;
+ }
+ else
+ {
+ cb.callout_number = 0;
+ cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE);
+ cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1;
+ cb.callout_string_length =
+ callout_length - (1 + 4*LINK_SIZE) - 2;
+ }
+
+ if ((rrc = mb->callout(&cb, mb->callout_data)) > 0)
+ RRETURN(MATCH_NOMATCH);
+ if (rrc < 0) RRETURN(rrc);
+ }
+ ecode += callout_length;
+ }
+ break;
+
+ /* Recursion either matches the current regex, or some subexpression. The
+ offset data is the offset to the starting bracket from the start of the
+ whole pattern. (This is so that it works from duplicated subpatterns.)
+
+ The state of the capturing groups is preserved over recursion, and
+ re-instated afterwards. We don't know how many are started and not yet
+ finished (offset_top records the completed total) so we just have to save
+ all the potential data. There may be up to 65535 such values, which is too
+ large to put on the stack, but using malloc for small numbers seems
+ expensive. As a compromise, the stack is used when there are no more than
+ OP_RECURSE_STACK_SAVE_MAX values to store; otherwise malloc is used.
+
+ There are also other values that have to be saved. We use a chained
+ sequence of blocks that actually live on the stack. Thanks to Robin Houston
+ for the original version of this logic. It has, however, been hacked around
+ a lot, so he is not to blame for the current way it works. */
+
+ case OP_RECURSE:
+ {
+ ovecsave_frame *fr;
+ recursion_info *ri;
+ uint32_t recno;
+
+ callpat = mb->start_code + GET(ecode, 1);
+ recno = (callpat == mb->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE);
+
+ /* Check for repeating a pattern recursion without advancing the subject
+ pointer. This should catch convoluted mutual recursions. (Some simple
+ cases are caught at compile time.) */
+
+ for (ri = mb->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && eptr == ri->subject_position)
+ RRETURN(PCRE2_ERROR_RECURSELOOP);
+
+ /* Add to "recursing stack" */
+
+ new_recursive.group_num = recno;
+ new_recursive.saved_capture_last = mb->capture_last;
+ new_recursive.subject_position = eptr;
+ new_recursive.prevrec = mb->recursive;
+ mb->recursive = &new_recursive;
+
+ /* Where to continue from afterwards */
+
+ ecode += 1 + LINK_SIZE;
+
+ /* When we are using the system stack for match() recursion we can call a
+ function that uses the system stack for preserving the ovector while
+ processing the pattern recursion, but only if the ovector is small
+ enough. */
+
+#ifndef HEAP_MATCH_RECURSE
+ if (mb->offset_end <= OP_RECURSE_STACK_SAVE_MAX)
+ {
+ rrc = op_recurse_ovecsave(eptr, callpat, mstart, offset_top, mb,
+ eptrb, rdepth);
+ mb->recursive = new_recursive.prevrec;
+ if (rrc != MATCH_MATCH && rrc != MATCH_ACCEPT) RRETURN(rrc);
+
+ /* Set where we got to in the subject, and reset the start, in case
+ it was changed by \K. This *is* propagated back out of a recursion,
+ for Perl compatibility. */
+
+ eptr = mb->end_match_ptr;
+ mstart = mb->start_match_ptr;
+ break; /* End of processing OP_RECURSE */
+ }
+#endif
+ /* If the ovector is too big, or if we are using the heap for match()
+ recursion, we have to use the heap for saving the ovector. Used ovecsave
+ frames are kept on a chain and re-used. This makes a small improvement in
+ execution time on Linux. */
+
+ if (mb->ovecsave_chain != NULL)
+ {
+ new_recursive.ovec_save = mb->ovecsave_chain->saved_ovec;
+ mb->ovecsave_chain = mb->ovecsave_chain->next;
+ }
+ else
+ {
+ fr = (ovecsave_frame *)(mb->memctl.malloc(sizeof(ovecsave_frame *) +
+ mb->offset_end * sizeof(PCRE2_SIZE), mb->memctl.memory_data));
+ if (fr == NULL) RRETURN(PCRE2_ERROR_NOMEMORY);
+ new_recursive.ovec_save = fr->saved_ovec;
+ }
+
+ memcpy(new_recursive.ovec_save, mb->ovector,
+ mb->offset_end * sizeof(PCRE2_SIZE));
+
+ /* Do the recursion. After processing each alternative, restore the
+ ovector data and the last captured value. This code has the same overall
+ logic as the code in the op_recurse_ovecsave() function, but is adapted
+ to use RMATCH/RRETURN and to release the heap block containing the saved
+ ovector. */
+
+ cbegroup = (*callpat >= OP_SBRA);
+ do
+ {
+ if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP;
+ RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
+ mb, eptrb, RM6);
+ memcpy(mb->ovector, new_recursive.ovec_save,
+ mb->offset_end * sizeof(PCRE2_SIZE));
+ mb->capture_last = new_recursive.saved_capture_last;
+ mb->recursive = new_recursive.prevrec;
+
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
+ {
+ fr = (ovecsave_frame *)
+ ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *));
+ fr->next = mb->ovecsave_chain;
+ mb->ovecsave_chain = fr;
+
+ /* Set where we got to in the subject, and reset the start, in case
+ it was changed by \K. This *is* propagated back out of a recursion,
+ for Perl compatibility. */
+
+ eptr = mb->end_match_ptr;
+ mstart = mb->start_match_ptr;
+ goto RECURSION_MATCHED; /* Exit loop; end processing */
+ }
+
+ /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
+ recursion; they cause a NOMATCH for the entire recursion. These codes
+ are defined in a range that can be tested for. */
+
+ if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
+ {
+ rrc = MATCH_NOMATCH;
+ goto RECURSION_RETURN;
+ }
+
+ /* Any return code other than NOMATCH is an error. */
+
+ if (rrc != MATCH_NOMATCH) goto RECURSION_RETURN;
+ mb->recursive = &new_recursive;
+ callpat += GET(callpat, 1);
+ }
+ while (*callpat == OP_ALT);
+
+ RECURSION_RETURN:
+ mb->recursive = new_recursive.prevrec;
+ fr = (ovecsave_frame *)
+ ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *));
+ fr->next = mb->ovecsave_chain;
+ mb->ovecsave_chain = fr;
+ RRETURN(rrc);
+ }
+
+ RECURSION_MATCHED:
+ break;
+
+ /* An alternation is the end of a branch; scan along to find the end of the
+ bracketed group and go to there. */
+
+ case OP_ALT:
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ break;
+
+ /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
+ indicating that it may occur zero times. It may repeat infinitely, or not
+ at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
+ with fixed upper repeat limits are compiled as a number of copies, with the
+ optional ones preceded by BRAZERO or BRAMINZERO. */
+
+ case OP_BRAZERO:
+ next_ecode = ecode + 1;
+ RMATCH(eptr, next_ecode, offset_top, mb, eptrb, RM10);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT);
+ ecode = next_ecode + 1 + LINK_SIZE;
+ break;
+
+ case OP_BRAMINZERO:
+ next_ecode = ecode + 1;
+ do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT);
+ RMATCH(eptr, next_ecode + 1+LINK_SIZE, offset_top, mb, eptrb, RM11);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode++;
+ break;
+
+ case OP_SKIPZERO:
+ next_ecode = ecode+1;
+ do next_ecode += GET(next_ecode,1); while (*next_ecode == OP_ALT);
+ ecode = next_ecode + 1 + LINK_SIZE;
+ break;
+
+ /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything
+ here; just jump to the group, with allow_zero set TRUE. */
+
+ case OP_BRAPOSZERO:
+ op = *(++ecode);
+ allow_zero = TRUE;
+ if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE;
+ goto POSSESSIVE_NON_CAPTURE;
+
+ /* End of a group, repeated or non-repeating. */
+
+ case OP_KET:
+ case OP_KETRMIN:
+ case OP_KETRMAX:
+ case OP_KETRPOS:
+ prev = ecode - GET(ecode, 1);
+
+ /* If this was a group that remembered the subject start, in order to break
+ infinite repeats of empty string matches, retrieve the subject start from
+ the chain. Otherwise, set it NULL. */
+
+ if (*prev >= OP_SBRA || *prev == OP_ONCE)
+ {
+ saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
+ eptrb = eptrb->epb_prev; /* Backup to previous group */
+ }
+ else saved_eptr = NULL;
+
+ /* If we are at the end of an assertion group or a non-capturing atomic
+ group, stop matching and return MATCH_MATCH, but record the current high
+ water mark for use by positive assertions. We also need to record the match
+ start in case it was changed by \K. */
+
+ if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
+ *prev == OP_ONCE_NC)
+ {
+ mb->end_match_ptr = eptr; /* For ONCE_NC */
+ mb->end_offset_top = offset_top;
+ mb->start_match_ptr = mstart;
+ if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
+ RRETURN(MATCH_MATCH); /* Sets mb->mark */
+ }
+
+ /* For capturing groups we have to check the group number back at the start
+ and if necessary complete handling an extraction by setting the offsets and
+ bumping the high water mark. Whole-pattern recursion is coded as a recurse
+ into group 0, so it won't be picked up here. Instead, we catch it when the
+ OP_END is reached. Other recursion is handled here. We just have to record
+ the current subject position and start match pointer and give a MATCH
+ return. */
+
+ if (*prev == OP_CBRA || *prev == OP_SCBRA ||
+ *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS)
+ {
+ number = GET2(prev, 1+LINK_SIZE);
+ offset = number << 1;
+
+ /* Handle a recursively called group. */
+
+ if (mb->recursive != NULL && mb->recursive->group_num == number)
+ {
+ mb->end_match_ptr = eptr;
+ mb->start_match_ptr = mstart;
+ if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
+ RRETURN(MATCH_MATCH);
+ }
+
+ /* Deal with capturing */
+
+ mb->capture_last = (mb->capture_last & OVFLMASK) | number;
+ if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else
+ {
+ /* If offset is greater than offset_top, it means that we are
+ "skipping" a capturing group, and that group's offsets must be marked
+ unset. In earlier versions of PCRE, all the offsets were unset at the
+ start of matching, but this doesn't work because atomic groups and
+ assertions can cause a value to be set that should later be unset.
+ Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as
+ part of the atomic group, but this is not on the final matching path,
+ so must be unset when 2 is set. (If there is no group 2, there is no
+ problem, because offset_top will then be 2, indicating no capture.) */
+
+ if (offset > offset_top)
+ {
+ PCRE2_SIZE *iptr = mb->ovector + offset_top;
+ PCRE2_SIZE *iend = mb->ovector + offset;
+ while (iptr < iend) *iptr++ = PCRE2_UNSET;
+ }
+
+ /* Now make the extraction */
+
+ mb->ovector[offset] = mb->ovector[mb->offset_end - number];
+ mb->ovector[offset+1] = eptr - mb->start_subject;
+ if (offset_top <= offset) offset_top = offset + 2;
+ }
+ }
+
+ /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
+ and return the MATCH_KETRPOS. This makes it possible to do the repeats one
+ at a time from the outer level, thus saving stack. This must precede the
+ empty string test - in this case that test is done at the outer level. */
+
+ if (*ecode == OP_KETRPOS)
+ {
+ mb->start_match_ptr = mstart; /* In case \K reset it */
+ mb->end_match_ptr = eptr;
+ mb->end_offset_top = offset_top;
+ if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
+ RRETURN(MATCH_KETRPOS);
+ }
+
+ /* For an ordinary non-repeating ket, just continue at this level. This
+ also happens for a repeating ket if no characters were matched in the
+ group. This is the forcible breaking of infinite loops as implemented in
+ Perl 5.005. For a non-repeating atomic group that includes captures,
+ establish a backup point by processing the rest of the pattern at a lower
+ level. If this results in a NOMATCH return, pass MATCH_ONCE back to the
+ original OP_ONCE level, thereby bypassing intermediate backup points, but
+ resetting any captures that happened along the way. */
+
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM12);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
+ }
+ ecode += 1 + LINK_SIZE; /* Carry on at this level */
+ break;
+ }
+
+ /* The normal repeating kets try the rest of the pattern or restart from
+ the preceding bracket, in the appropriate order. In the second case, we can
+ use tail recursion to avoid using another stack frame, unless we have an
+ an atomic group or an unlimited repeat of a group that can match an empty
+ string. */
+
+ if (*ecode == OP_KETRMIN)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM7);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, prev, offset_top, mb, eptrb, RM8);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
+ }
+ if (*prev >= OP_SBRA) /* Could match an empty string */
+ {
+ RMATCH(eptr, prev, offset_top, mb, eptrb, RM50);
+ RRETURN(rrc);
+ }
+ ecode = prev;
+ goto TAIL_RECURSE;
+ }
+ else /* OP_KETRMAX */
+ {
+ RMATCH(eptr, prev, offset_top, mb, eptrb, RM13);
+ if (rrc == MATCH_ONCE && mb->once_target == prev) rrc = MATCH_NOMATCH;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM9);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ mb->once_target = prev;
+ RRETURN(MATCH_ONCE);
+ }
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+ /* Control never gets here */
+
+ /* Not multiline mode: start of subject assertion, unless notbol. */
+
+ case OP_CIRC:
+ if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject)
+ RRETURN(MATCH_NOMATCH);
+
+ /* Start of subject assertion */
+
+ case OP_SOD:
+ if (eptr != mb->start_subject) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Multiline mode: start of subject unless notbol, or after any newline
+ except for one at the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */
+
+ case OP_CIRCM:
+ if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject)
+ RRETURN(MATCH_NOMATCH);
+ if (eptr != mb->start_subject &&
+ ((eptr == mb->end_subject &&
+ (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) ||
+ !WAS_NEWLINE(eptr)))
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Start of match assertion */
+
+ case OP_SOM:
+ if (eptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Reset the start of match point */
+
+ case OP_SET_SOM:
+ mstart = eptr;
+ ecode++;
+ break;
+
+ /* Multiline mode: assert before any newline, or before end of subject
+ unless noteol is set. */
+
+ case OP_DOLLM:
+ if (eptr < mb->end_subject)
+ {
+ if (!IS_NEWLINE(eptr))
+ {
+ if (mb->partial != 0 &&
+ eptr + 1 >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ UCHAR21TEST(eptr) == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+ {
+ if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
+ }
+ ecode++;
+ break;
+
+ /* Not multiline mode: assert before a terminating newline or before end of
+ subject unless noteol is set. */
+
+ case OP_DOLL:
+ if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
+ if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;
+
+ /* ... else fall through for endonly */
+
+ /* End of subject assertion (\z) */
+
+ case OP_EOD:
+ if (eptr < mb->end_subject) RRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
+ ecode++;
+ break;
+
+ /* End of subject or ending \n assertion (\Z) */
+
+ case OP_EODN:
+ ASSERT_NL_OR_EOS:
+ if (eptr < mb->end_subject &&
+ (!IS_NEWLINE(eptr) || eptr != mb->end_subject - mb->nllen))
+ {
+ if (mb->partial != 0 &&
+ eptr + 1 >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ UCHAR21TEST(eptr) == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ /* Either at end of string or \n before end. */
+
+ SCHECK_PARTIAL();
+ ecode++;
+ break;
+
+ /* Word boundary assertions */
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ {
+
+ /* Find out if the previous and current characters are "word" characters.
+ It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
+ be "non-word" characters. Remember the earliest consulted character for
+ partial matching. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ /* Get status of previous character */
+
+ if (eptr == mb->start_subject) prev_is_word = FALSE; else
+ {
+ PCRE2_SPTR lastptr = eptr - 1;
+ BACKCHAR(lastptr);
+ if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr;
+ GETCHAR(c, lastptr);
+ if ((mb->poptions & PCRE2_UCP) != 0)
+ {
+ if (c == '_') prev_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ prev_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+ prev_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0;
+ }
+
+ /* Get status of next character */
+
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ cur_is_word = FALSE;
+ }
+ else
+ {
+ PCRE2_SPTR nextptr = eptr + 1;
+ FORWARDCHARTEST(nextptr, mb->end_subject);
+ if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr;
+ GETCHAR(c, eptr);
+ if ((mb->poptions & PCRE2_UCP) != 0)
+ {
+ if (c == '_') cur_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ cur_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+ cur_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0;
+ }
+ }
+ else
+#endif /* SUPPORT UTF */
+
+ /* Not in UTF-8 mode, but we may still have PCRE2_UCP set, and for
+ consistency with the behaviour of \w we do use it in this case. */
+
+ {
+ /* Get status of previous character */
+
+ if (eptr == mb->start_subject) prev_is_word = FALSE; else
+ {
+ if (eptr <= mb->start_used_ptr) mb->start_used_ptr = eptr - 1;
+#ifdef SUPPORT_UNICODE
+ if ((mb->poptions & PCRE2_UCP) != 0)
+ {
+ c = eptr[-1];
+ if (c == '_') prev_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ prev_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ prev_is_word = MAX_255(eptr[-1])
+ && ((mb->ctypes[eptr[-1]] & ctype_word) != 0);
+ }
+
+ /* Get status of next character */
+
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ cur_is_word = FALSE;
+ }
+ else
+ {
+ if (eptr >= mb->last_used_ptr) mb->last_used_ptr = eptr + 1;
+#ifdef SUPPORT_UNICODE
+ if ((mb->poptions & PCRE2_UCP) != 0)
+ {
+ c = *eptr;
+ if (c == '_') cur_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ cur_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ cur_is_word = MAX_255(*eptr)
+ && ((mb->ctypes[*eptr] & ctype_word) != 0);
+ }
+ }
+
+ /* Now see if the situation is what we want */
+
+ if ((*ecode++ == OP_WORD_BOUNDARY)?
+ cur_is_word == prev_is_word : cur_is_word != prev_is_word)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* Match any single character type except newline; have to take care with
+ CRLF newlines and partial matching. */
+
+ case OP_ANY:
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ if (mb->partial != 0 &&
+ eptr == mb->end_subject - 1 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ UCHAR21TEST(eptr) == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+
+ /* Fall through */
+
+ /* Match any single character whatsoever. */
+
+ case OP_ALLANY:
+ if (eptr >= mb->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+#ifdef SUPPORT_UNICODE
+ if (utf) ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+#endif
+ ecode++;
+ break;
+
+ /* Match a single code unit, even in UTF-8 mode. This opcode really does
+ match any code unit, even newline. (It really should be called ANYCODEUNIT,
+ of course - the byte name is from pre-16 bit days.) */
+
+ case OP_ANYBYTE:
+ if (eptr >= mb->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+ ecode++;
+ break;
+
+ case OP_NOT_DIGIT:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#ifdef SUPPORT_WIDE_CHARS
+ c < 256 &&
+#endif
+ (mb->ctypes[c] & ctype_digit) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_DIGIT:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#ifdef SUPPORT_WIDE_CHARS
+ c > 255 ||
+#endif
+ (mb->ctypes[c] & ctype_digit) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#ifdef SUPPORT_WIDE_CHARS
+ c < 256 &&
+#endif
+ (mb->ctypes[c] & ctype_space) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_WHITESPACE:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#ifdef SUPPORT_WIDE_CHARS
+ c > 255 ||
+#endif
+ (mb->ctypes[c] & ctype_space) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#ifdef SUPPORT_WIDE_CHARS
+ c < 256 &&
+#endif
+ (mb->ctypes[c] & ctype_word) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_WORDCHAR:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#ifdef SUPPORT_WIDE_CHARS
+ c > 255 ||
+#endif
+ (mb->ctypes[c] & ctype_word) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_ANYNL:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case CHAR_CR:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ }
+ else if (UCHAR21TEST(eptr) == CHAR_LF) eptr++;
+ break;
+
+ case CHAR_LF:
+ break;
+
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ ecode++;
+ break;
+
+ case OP_NOT_HSPACE:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */
+ default: break;
+ }
+ ecode++;
+ break;
+
+ case OP_HSPACE:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ HSPACE_CASES: break; /* Byte and multibyte cases */
+ default: RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ break;
+
+ case OP_NOT_VSPACE:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ VSPACE_CASES: RRETURN(MATCH_NOMATCH);
+ default: break;
+ }
+ ecode++;
+ break;
+
+ case OP_VSPACE:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ VSPACE_CASES: break;
+ default: RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ break;
+
+#ifdef SUPPORT_UNICODE
+ /* Check the next character by Unicode property. We will get here only
+ if the support is in the binary; otherwise a compile-time error occurs. */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ {
+ const uint32_t *cp;
+ const ucd_record *prop = GET_UCD(c);
+
+ switch(ecode[1])
+ {
+ case PT_ANY:
+ if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_LAMP:
+ if ((prop->chartype == ucp_Lu ||
+ prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_GC:
+ if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_PC:
+ if ((ecode[2] != prop->chartype) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_SC:
+ if ((ecode[2] != prop->script) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ /* These are specials */
+
+ case PT_ALNUM:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) ==
+ (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ break;
+
+ case PT_WORD:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_CLIST:
+ cp = PRIV(ucd_caseless_sets) + ecode[2];
+ for (;;)
+ {
+ if (c < *cp)
+ { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; }
+ if (c == *cp++)
+ { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } }
+ }
+ break;
+
+ case PT_UCNC:
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ /* This should never occur */
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+
+ ecode += 3;
+ }
+ break;
+
+ /* Match an extended Unicode sequence. We will get here only if the support
+ is in the binary; otherwise a compile-time error occurs. */
+
+ case OP_EXTUNI:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ else
+ {
+ int lgb, rgb;
+ GETCHARINCTEST(c, eptr);
+ lgb = UCD_GRAPHBREAK(c);
+ while (eptr < mb->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ rgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ lgb = rgb;
+ eptr += len;
+ }
+ }
+ CHECK_PARTIAL();
+ ecode++;
+ break;
+#endif /* SUPPORT_UNICODE */
+
+
+ /* Match a back reference, possibly repeatedly. Look past the end of the
+ item to see if there is repeat information following.
+
+ The OP_REF and OP_REFI opcodes are used for a reference to a numbered group
+ or to a non-duplicated named group. For a duplicated named group, OP_DNREF
+ and OP_DNREFI are used. In this case we must scan the list of groups to
+ which the name refers, and use the first one that is set. */
+
+ case OP_DNREF:
+ case OP_DNREFI:
+ caseless = op == OP_DNREFI;
+ {
+ int count = GET2(ecode, 1+IMM2_SIZE);
+ PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size;
+ ecode += 1 + 2*IMM2_SIZE;
+
+ /* Initializing 'offset' avoids a compiler warning in the REF_REPEAT
+ code. */
+
+ offset = 0;
+ while (count-- > 0)
+ {
+ offset = GET2(slot, 0) << 1;
+ if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET) break;
+ slot += mb->name_entry_size;
+ }
+ }
+ goto REF_REPEAT;
+
+ case OP_REF:
+ case OP_REFI:
+ caseless = op == OP_REFI;
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
+ ecode += 1 + IMM2_SIZE;
+
+ /* Set up for repetition, or handle the non-repeated case */
+
+ REF_REPEAT:
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ {
+ int rc = match_ref(offset, offset_top, eptr, mb, caseless, &length);
+ if (rc != 0)
+ {
+ if (rc > 0) eptr = mb->end_subject; /* Partial match */
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ eptr += length;
+ continue; /* With the main loop */
+ }
+
+ /* Handle repeated back references. If a set group has length zero, just
+ continue with the main loop, because it matches however many times. For an
+ unset reference, if the minimum is zero, we can also just continue. We an
+ also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset
+ group be have as a zero-length group. For any other unset cases, carrying
+ on will result in NOMATCH. */
+
+ if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET)
+ {
+ if (mb->ovector[offset] == mb->ovector[offset + 1]) continue;
+ }
+ else /* Group is not set */
+ {
+ if (min == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
+ continue;
+ }
+
+ /* First, ensure the minimum number of matches are present. */
+
+ for (i = 1; i <= min; i++)
+ {
+ PCRE2_SIZE slength;
+ int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength);
+ if (rc != 0)
+ {
+ if (rc > 0) eptr = mb->end_subject; /* Partial match */
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += slength;
+ }
+
+ /* If min = max, continue at the same level without recursion.
+ They are not both allowed to be zero. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep trying and advancing the pointer */
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ int rc;
+ PCRE2_SIZE slength;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM14);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength);
+ if (rc != 0)
+ {
+ if (rc > 0) eptr = mb->end_subject; /* Partial match */
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += slength;
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest string and work backwards, as long as
+ the matched lengths for each iteration are the same. */
+
+ else
+ {
+ BOOL samelengths = TRUE;
+ pp = eptr;
+ length = mb->ovector[offset+1] - mb->ovector[offset];
+
+ for (i = min; i < max; i++)
+ {
+ PCRE2_SIZE slength;
+ int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength);
+
+ if (rc != 0)
+ {
+ /* Can't use CHECK_PARTIAL because we don't want to update eptr in
+ the soft partial matching case. */
+
+ if (rc > 0 && mb->partial != 0 &&
+ mb->end_subject > mb->start_used_ptr)
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ break;
+ }
+
+ if (slength != length) samelengths = FALSE;
+ eptr += slength;
+ }
+
+ /* If the length matched for each repetition is the same as the length of
+ the captured group, we can easily work backwards. This is the normal
+ case. However, in caseless UTF-8 mode there are pairs of case-equivalent
+ characters whose lengths (in terms of code units) differ. However, this
+ is very rare, so we handle it by re-matching fewer and fewer times. */
+
+ if (samelengths)
+ {
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM15);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr -= length;
+ }
+ }
+
+ /* The rare case of non-matching lengths. Re-scan the repetition for each
+ iteration. We know that match_ref() will succeed every time. */
+
+ else
+ {
+ max = i;
+ for (;;)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM68);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr == pp) break; /* Failed after minimal repetition */
+ eptr = pp;
+ max--;
+ for (i = min; i < max; i++)
+ {
+ PCRE2_SIZE slength;
+ (void)match_ref(offset, offset_top, eptr, mb, caseless, &slength);
+ eptr += slength;
+ }
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* Match a bit-mapped character class, possibly repeatedly. This op code is
+ used when all the characters in the class have values in the range 0-255,
+ and either the matching is caseful, or the characters are in the range
+ 0-127 when UTF-8 processing is enabled. The only difference between
+ OP_CLASS and OP_NCLASS occurs when a data character outside the range is
+ encountered.
+
+ First, look past the end of the item to see if there is repeat information
+ following. Then obey similar code to character type repeats - written out
+ again for speed. */
+
+ case OP_NCLASS:
+ case OP_CLASS:
+ {
+ /* The data variable is saved across frames, so the byte map needs to
+ be stored there. */
+#define BYTE_MAP ((uint8_t *)data)
+ data = ecode + 1; /* Save for matching */
+ ecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
+ else possessive = TRUE;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ possessive = (*ecode == OP_CRPOSRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ min = max = 1;
+ break;
+ }
+
+ /* First, ensure the minimum number of matches are present. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ c = *eptr++;
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ /* If max == min we can continue with the main loop without the
+ need to recurse. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep testing the rest of the expression and advancing
+ the pointer while it matches the class. */
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM16);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM17);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ c = *eptr++;
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest possible run, then work backwards. */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) break;
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
+ eptr += len;
+ }
+
+ if (possessive) continue; /* No backtracking */
+
+ for (;;)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM18);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) break;
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
+ eptr++;
+ }
+
+ if (possessive) continue; /* No backtracking */
+
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM19);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+#undef BYTE_MAP
+ }
+ /* Control never gets here */
+
+
+ /* Match an extended character class. In the 8-bit library, this opcode is
+ encountered only when UTF-8 mode mode is supported. In the 16-bit and
+ 32-bit libraries, codepoints greater than 255 may be encountered even when
+ UTF is not supported. */
+
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ {
+ data = ecode + 1 + LINK_SIZE; /* Save for matching */
+ ecode += GET(ecode, 1); /* Advance past the item */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
+ else possessive = TRUE;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ possessive = (*ecode == OP_CRPOSRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ min = max = 1;
+ break;
+ }
+
+ /* First, ensure the minimum number of matches are present. */
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
+ }
+
+ /* If max == min we can continue with the main loop without the
+ need to recurse. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep testing the rest of the expression and advancing
+ the pointer while it matches the class. */
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM20);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest possible run, then work backwards. */
+
+ else
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+#ifdef SUPPORT_UNICODE
+ GETCHARLENTEST(c, eptr, len);
+#else
+ c = *eptr;
+#endif
+ if (!PRIV(xclass)(c, data, utf)) break;
+ eptr += len;
+ }
+
+ if (possessive) continue; /* No backtracking */
+
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM21);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+#ifdef SUPPORT_UNICODE
+ if (utf) BACKCHAR(eptr);
+#endif
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ /* Control never gets here */
+ }
+#endif /* End of XCLASS */
+
+ /* Match a single character, casefully */
+
+ case OP_CHAR:
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ length = 1;
+ ecode++;
+ GETCHARLEN(fc, ecode, length);
+ if (length > (PCRE2_SIZE)(mb->end_subject - eptr))
+ {
+ CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
+ RRETURN(MATCH_NOMATCH);
+ }
+ for (; length > 0; length--)
+ {
+ if (*ecode++ != UCHAR21INC(eptr)) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ if (mb->end_subject - eptr < 1)
+ {
+ SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
+ ecode += 2;
+ }
+ break;
+
+ /* Match a single character, caselessly. If we are at the end of the
+ subject, give up immediately. */
+
+ case OP_CHARI:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ length = 1;
+ ecode++;
+ GETCHARLEN(fc, ecode, length);
+
+ /* If the pattern character's value is < 128, we have only one byte, and
+ we know that its other case must also be one byte long, so we can use the
+ fast lookup table. We know that there is at least one byte left in the
+ subject. */
+
+ if (fc < 128)
+ {
+ uint32_t cc = UCHAR21(eptr);
+ if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ eptr++;
+ }
+
+ /* Otherwise we must pick up the subject character. Note that we cannot
+ use the value of "length" to check for sufficient bytes left, because the
+ other case of the character may have more or fewer bytes. */
+
+ else
+ {
+ uint32_t dc;
+ GETCHARINC(dc, eptr);
+ ecode += length;
+
+ /* If we have Unicode property support, we can use it to test the other
+ case of the character, if there is one. */
+
+ if (fc != dc)
+ {
+#ifdef SUPPORT_UNICODE
+ if (dc != UCD_OTHERCASE(fc))
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+
+ /* Not UTF mode */
+ {
+ if (TABLE_GET(ecode[1], mb->lcc, ecode[1])
+ != TABLE_GET(*eptr, mb->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ecode += 2;
+ }
+ break;
+
+ /* Match a single character repeatedly. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ min = max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATCHAR;
+
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ possessive = TRUE;
+ /* Fall through */
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATCHAR;
+
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI);
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single-character matches. We first check
+ for the minimum number of characters. If the minimum equals the maximum, we
+ are done. Otherwise, if minimizing, check the rest of the pattern for a
+ match; if there isn't one, advance up to the maximum, one character at a
+ time.
+
+ If maximizing, advance up to the maximum number of matching characters,
+ until eptr is past the end of the maximum run. If possessive, we are
+ then done (no backing up). Otherwise, match at this position; anything
+ other than no match is immediately returned. For nomatch, back up one
+ character, unless we are matching \R and the last thing matched was
+ \r\n, in which case, back up two bytes. When we reach the first optional
+ character position, we can save stack by doing a tail recurse.
+
+ The various UTF/non-UTF and caseful/caseless cases are handled separately,
+ for speed. */
+
+ REPEATCHAR:
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ length = 1;
+ charptr = ecode;
+ GETCHARLEN(fc, ecode, length);
+ ecode += length;
+
+ /* Handle multibyte character matching specially here. There is
+ support for caseless matching if UCP support is present. */
+
+ if (length > 1)
+ {
+ uint32_t othercase;
+ if (op >= OP_STARI && /* Caseless */
+ (othercase = UCD_OTHERCASE(fc)) != fc)
+ oclength = PRIV(ord2utf)(othercase, occhars);
+ else oclength = 0;
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr <= mb->end_subject - length &&
+ memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length;
+ else if (oclength > 0 &&
+ eptr <= mb->end_subject - oclength &&
+ memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength;
+ else
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM22);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr <= mb->end_subject - length &&
+ memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length;
+ else if (oclength > 0 &&
+ eptr <= mb->end_subject - oclength &&
+ memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength;
+ else
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr <= mb->end_subject - length &&
+ memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length;
+ else if (oclength > 0 &&
+ eptr <= mb->end_subject - oclength &&
+ memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength;
+ else
+ {
+ CHECK_PARTIAL();
+ break;
+ }
+ }
+
+ if (possessive) continue; /* No backtracking */
+
+ /* After \C in UTF mode, pp might be in the middle of a Unicode
+ character. Use <= pp to ensure backtracking doesn't go too far. */
+
+ for(;;)
+ {
+ if (eptr <= pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM23);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ BACKCHAR(eptr);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If the length of a UTF-8 character is 1, we fall through here, and
+ obey the code as for non-UTF-8 characters below, though in this case the
+ value of fc will always be < 128. */
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+
+ /* When not in UTF-8 mode, load a single-byte character. */
+ fc = *ecode++;
+
+ /* The value of fc at this point is always one character, though we may
+ or may not be in UTF mode. The code is duplicated for the caseless and
+ caseful cases, for speed, since matching characters is likely to be quite
+ common. First, ensure the minimum number of matches are present. If min =
+ max, continue at the same level without recursing. Otherwise, if
+ minimizing, keep trying the rest of the expression and advancing one
+ matching character if failing, up to the maximum. Alternatively, if
+ maximizing, find the maximum number of characters and work backwards. */
+
+ if (op >= OP_STARI) /* Caseless */
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ /* fc must be < 128 if UTF is enabled. */
+ foc = mb->fcc[fc];
+#else
+#ifdef SUPPORT_UNICODE
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+ else
+#endif /* SUPPORT_UNICODE */
+ foc = TABLE_GET(fc, mb->fcc, fc);
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+
+ for (i = 1; i <= min; i++)
+ {
+ uint32_t cc; /* Faster than PCRE2_UCHAR */
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ cc = UCHAR21TEST(eptr);
+ if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ if (min == max) continue;
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ uint32_t cc; /* Faster than PCRE2_UCHAR */
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM24);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ cc = UCHAR21TEST(eptr);
+ if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ /* Control never gets here */
+ }
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ uint32_t cc; /* Faster than PCRE2_UCHAR */
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ cc = UCHAR21TEST(eptr);
+ if (fc != cc && foc != cc) break;
+ eptr++;
+ }
+ if (possessive) continue; /* No backtracking */
+ for (;;)
+ {
+ if (eptr == pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM25);
+ eptr--;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ }
+ /* Control never gets here */
+ }
+ }
+
+ /* Caseful comparisons (includes all multi-byte characters) */
+
+ else
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH);
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM26);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc != UCHAR21TEST(eptr)) break;
+ eptr++;
+ }
+ if (possessive) continue; /* No backtracking */
+ for (;;)
+ {
+ if (eptr == pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM27);
+ eptr--;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ }
+ /* Control never gets here */
+ }
+ }
+ /* Control never gets here */
+
+ /* Match a negated single one-byte character. The character we are
+ checking can be multibyte. */
+
+ case OP_NOT:
+ case OP_NOTI:
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t ch, och;
+
+ ecode++;
+ GETCHARINC(ch, ecode);
+ GETCHARINC(c, eptr);
+
+ if (op == OP_NOT)
+ {
+ if (ch == c) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ {
+ if (ch > 127)
+ och = UCD_OTHERCASE(ch);
+ else
+ och = TABLE_GET(ch, mb->fcc, ch);
+ if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+ {
+ uint32_t ch = ecode[1];
+ c = *eptr++;
+ if (ch == c || (op == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == c))
+ RRETURN(MATCH_NOMATCH);
+ ecode += 2;
+ }
+ break;
+
+ /* Match a negated single one-byte character repeatedly. This is almost a
+ repeat of the code for a repeated single character, but I haven't found a
+ nice way of commoning these up that doesn't require a test of the
+ positive/negative option for each character match. Maybe that wouldn't add
+ very much to the time taken, but character matching *is* what this is all
+ about... */
+
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ min = max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ possessive = TRUE;
+ min = 0;
+ max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single-byte matches. */
+
+ REPEATNOTCHAR:
+ GETCHARINCTEST(fc, ecode);
+
+ /* The code is duplicated for the caseless and caseful cases, for speed,
+ since matching characters is likely to be quite common. First, ensure the
+ minimum number of matches are present. If min = max, continue at the same
+ level without recursing. Otherwise, if minimizing, keep trying the rest of
+ the expression and advancing one matching character if failing, up to the
+ maximum. Alternatively, if maximizing, find the maximum number of
+ characters and work backwards. */
+
+ if (op >= OP_NOTSTARI) /* Caseless */
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+ else
+#endif /* SUPPORT_UNICODE */
+ foc = TABLE_GET(fc, mb->fcc, fc);
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t d;
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t d;
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM28);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif /*SUPPORT_UNICODE */
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM29);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* Maximize case */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t d;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(d, eptr, len);
+ if (fc == d || (uint32_t)foc == d) break;
+ eptr += len;
+ }
+ if (possessive) continue; /* No backtracking */
+
+ /* After \C in UTF mode, pp might be in the middle of a Unicode
+ character. Use <= pp to ensure backtracking doesn't go too far. */
+
+ for(;;)
+ {
+ if (eptr <= pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM30);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc == *eptr || foc == *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue; /* No backtracking */
+ for (;;)
+ {
+ if (eptr == pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM31);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+ /* Control never gets here */
+ }
+ }
+
+ /* Caseful comparisons */
+
+ else
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t d;
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t d;
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM32);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM33);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* Maximize case */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t d;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(d, eptr, len);
+ if (fc == d) break;
+ eptr += len;
+ }
+ if (possessive) continue; /* No backtracking */
+
+ /* After \C in UTF mode, pp might be in the middle of a Unicode
+ character. Use <= pp to ensure backtracking doesn't go too far. */
+
+ for(;;)
+ {
+ if (eptr <= pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM34);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc == *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue; /* No backtracking */
+ for (;;)
+ {
+ if (eptr == pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM35);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+ /* Control never gets here */
+ }
+ }
+ /* Control never gets here */
+
+ /* Match a single character type repeatedly; several different opcodes
+ share code. This is very similar to the code for single characters, but we
+ repeat it in the interests of efficiency. */
+
+ case OP_TYPEEXACT:
+ min = max = GET2(ecode, 1);
+ minimize = TRUE;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_TYPEMINUPTO;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSSTAR:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSPLUS:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSQUERY:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSUPTO:
+ possessive = TRUE;
+ min = 0;
+ max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ c = *ecode++ - OP_TYPESTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single character type matches. Note that
+ in UTF-8 mode, '.' matches a character of any length, but for the other
+ character types, the valid characters are all one-byte long. */
+
+ REPEATTYPE:
+ ctype = *ecode++; /* Code for the character type */
+
+#ifdef SUPPORT_UNICODE
+ if (ctype == OP_PROP || ctype == OP_NOTPROP)
+ {
+ prop_fail_result = ctype == OP_NOTPROP;
+ prop_type = *ecode++;
+ prop_value = *ecode++;
+ }
+ else prop_type = -1;
+#endif
+
+ /* First, ensure the minimum number of matches are present. Use inline
+ code for maximizing the speed, and do the type test once at the start
+ (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
+ is tidier. Also separate the UCP code, which can be the same for both UTF-8
+ and single-bytes. */
+
+ if (min > 0)
+ {
+#ifdef SUPPORT_UNICODE
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ }
+ break;
+
+ case PT_LAMP:
+ for (i = 1; i <= min; i++)
+ {
+ int chartype;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_GC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_PC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_SC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_ALNUM:
+ for (i = 1; i <= min; i++)
+ {
+ int category;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ break;
+
+ case PT_WORD:
+ for (i = 1; i <= min; i++)
+ {
+ int category;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_CLIST:
+ for (i = 1; i <= min; i++)
+ {
+ const uint32_t *cp;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ cp = PRIV(ucd_caseless_sets) + prop_value;
+ for (;;)
+ {
+ if (c < *cp)
+ { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
+ if (c == *cp++)
+ { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
+ }
+ }
+ break;
+
+ case PT_UCNC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* This should not occur */
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ else
+ {
+ int lgb, rgb;
+ GETCHARINCTEST(c, eptr);
+ lgb = UCD_GRAPHBREAK(c);
+ while (eptr < mb->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ rgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ lgb = rgb;
+ eptr += len;
+ }
+ }
+ CHECK_PARTIAL();
+ }
+ }
+
+ else
+#endif /* SUPPORT_UNICODE */
+
+/* Handle all other cases when the coding is UTF-8 */
+
+#ifdef SUPPORT_UNICODE
+ if (utf) switch(ctype)
+ {
+ case OP_ANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ if (mb->partial != 0 &&
+ eptr + 1 >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ UCHAR21(eptr) == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ eptr++;
+ ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_ALLANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+ ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_ANYBYTE:
+ if (eptr > mb->end_subject - min) RRETURN(MATCH_NOMATCH);
+ eptr += min;
+ break;
+
+ case OP_ANYNL:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case CHAR_CR:
+ if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++;
+ break;
+
+ case CHAR_LF:
+ break;
+
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */
+ default: break;
+ }
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ HSPACE_CASES: break; /* Byte and multibyte cases */
+ default: RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ VSPACE_CASES: RRETURN(MATCH_NOMATCH);
+ default: break;
+ }
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ VSPACE_CASES: break;
+ default: RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c < 128 && (mb->ctypes[c] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ uint32_t cc;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ cc = UCHAR21(eptr);
+ if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ uint32_t cc;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ cc = UCHAR21(eptr);
+ if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ uint32_t cc;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ cc = UCHAR21(eptr);
+ if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ uint32_t cc;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ cc = UCHAR21(eptr);
+ if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ uint32_t cc;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ cc = UCHAR21(eptr);
+ if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ } /* End switch(ctype) */
+
+ else
+#endif /* SUPPORT_UNICODE */
+
+ /* Code for the non-UTF-8 case for minimum matching of operators other
+ than OP_PROP and OP_NOTPROP. */
+
+ switch(ctype)
+ {
+ case OP_ANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ if (mb->partial != 0 &&
+ eptr + 1 >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ eptr++;
+ }
+ break;
+
+ case OP_ALLANY:
+ if (eptr > mb->end_subject - min)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += min;
+ break;
+
+ case OP_ANYBYTE:
+ if (eptr > mb->end_subject - min)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += min;
+ break;
+
+ case OP_ANYNL:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case CHAR_CR:
+ if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++;
+ break;
+
+ case CHAR_LF:
+ break;
+
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: break;
+ HSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ HSPACE_MULTIBYTE_CASES:
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ HSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ HSPACE_MULTIBYTE_CASES:
+#endif
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ VSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ VSPACE_MULTIBYTE_CASES:
+#endif
+ RRETURN(MATCH_NOMATCH);
+ default: break;
+ }
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ VSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ VSPACE_MULTIBYTE_CASES:
+#endif
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+ }
+
+ /* If min = max, continue at the same level without recursing */
+
+ if (min == max) continue;
+
+ /* If minimizing, we have to test the rest of the pattern before each
+ subsequent match. Again, separate the UTF-8 case for speed, and also
+ separate the UCP cases. */
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UNICODE
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM36);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_LAMP:
+ for (fi = min;; fi++)
+ {
+ int chartype;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM37);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_GC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM38);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_PC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM39);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_SC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM40);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_ALNUM:
+ for (fi = min;; fi++)
+ {
+ int category;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM59);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM61);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ /* Control never gets here */
+
+ case PT_WORD:
+ for (fi = min;; fi++)
+ {
+ int category;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM62);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L ||
+ category == ucp_N ||
+ c == CHAR_UNDERSCORE)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_CLIST:
+ for (fi = min;; fi++)
+ {
+ const uint32_t *cp;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM67);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ cp = PRIV(ucd_caseless_sets) + prop_value;
+ for (;;)
+ {
+ if (c < *cp)
+ { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
+ if (c == *cp++)
+ { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
+ }
+ }
+ /* Control never gets here */
+
+ case PT_UCNC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM60);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* This should never occur */
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM41);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ else
+ {
+ int lgb, rgb;
+ GETCHARINCTEST(c, eptr);
+ lgb = UCD_GRAPHBREAK(c);
+ while (eptr < mb->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ rgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ lgb = rgb;
+ eptr += len;
+ }
+ }
+ CHECK_PARTIAL();
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM42);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ctype == OP_ANY && IS_NEWLINE(eptr))
+ RRETURN(MATCH_NOMATCH);
+ GETCHARINC(c, eptr);
+ switch(ctype)
+ {
+ case OP_ANY: /* This is the non-NL case */
+ if (mb->partial != 0 && /* Take care with CRLF partial */
+ eptr >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ break;
+
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ break;
+
+ case OP_ANYNL:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case CHAR_CR:
+ if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++;
+ break;
+
+ case CHAR_LF:
+ break;
+
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(c)
+ {
+ HSPACE_CASES: RRETURN(MATCH_NOMATCH);
+ default: break;
+ }
+ break;
+
+ case OP_HSPACE:
+ switch(c)
+ {
+ HSPACE_CASES: break;
+ default: RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(c)
+ {
+ VSPACE_CASES: RRETURN(MATCH_NOMATCH);
+ default: break;
+ }
+ break;
+
+ case OP_VSPACE:
+ switch(c)
+ {
+ VSPACE_CASES: break;
+ default: RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_DIGIT:
+ if (c >= 256 || (mb->ctypes[c] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (c < 256 && (mb->ctypes[c] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WHITESPACE:
+ if (c >= 256 || (mb->ctypes[c] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (c < 256 && (mb->ctypes[c] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WORDCHAR:
+ if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM43);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ctype == OP_ANY && IS_NEWLINE(eptr))
+ RRETURN(MATCH_NOMATCH);
+ c = *eptr++;
+ switch(ctype)
+ {
+ case OP_ANY: /* This is the non-NL case */
+ if (mb->partial != 0 && /* Take care with CRLF partial */
+ eptr >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ break;
+
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ break;
+
+ case OP_ANYNL:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case CHAR_CR:
+ if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++;
+ break;
+
+ case CHAR_LF:
+ break;
+
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(c)
+ {
+ default: break;
+ HSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ HSPACE_MULTIBYTE_CASES:
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_HSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ HSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ HSPACE_MULTIBYTE_CASES:
+#endif
+ break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(c)
+ {
+ default: break;
+ VSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ VSPACE_MULTIBYTE_CASES:
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_VSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ VSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ VSPACE_MULTIBYTE_CASES:
+#endif
+ break;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ if (MAX_255(c) && (mb->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_DIGIT:
+ if (!MAX_255(c) || (mb->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (MAX_255(c) && (mb->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WHITESPACE:
+ if (!MAX_255(c) || (mb->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (MAX_255(c) && (mb->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WORDCHAR:
+ if (!MAX_255(c) || (mb->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, it is worth using inline code for speed, doing the type
+ test once at the start (i.e. keep it out of the loop). Again, keep the
+ UTF-8 and UCP stuff separate. */
+
+ else
+ {
+ pp = eptr; /* Remember where we started */
+
+#ifdef SUPPORT_UNICODE
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if (prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_LAMP:
+ for (i = min; i < max; i++)
+ {
+ int chartype;
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_GC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_PC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_SC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_ALNUM:
+ for (i = min; i < max; i++)
+ {
+ int category;
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) goto ENDLOOP99; /* Break the loop */
+ break;
+
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ goto ENDLOOP99; /* Break the loop */
+ break;
+ }
+ eptr+= len;
+ }
+ ENDLOOP99:
+ break;
+
+ case PT_WORD:
+ for (i = min; i < max; i++)
+ {
+ int category;
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N ||
+ c == CHAR_UNDERSCORE) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_CLIST:
+ for (i = min; i < max; i++)
+ {
+ const uint32_t *cp;
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ cp = PRIV(ucd_caseless_sets) + prop_value;
+ for (;;)
+ {
+ if (c < *cp)
+ { if (prop_fail_result) break; else goto GOT_MAX; }
+ if (c == *cp++)
+ { if (prop_fail_result) goto GOT_MAX; else break; }
+ }
+ eptr += len;
+ }
+ GOT_MAX:
+ break;
+
+ case PT_UCNC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ break;
+ eptr += len;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+
+ /* eptr is now past the end of the maximum run */
+
+ if (possessive) continue; /* No backtracking */
+
+ /* After \C in UTF mode, pp might be in the middle of a Unicode
+ character. Use <= pp to ensure backtracking doesn't go too far. */
+
+ for(;;)
+ {
+ if (eptr <= pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM44);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ if (utf) BACKCHAR(eptr);
+ }
+ }
+
+ /* Match extended Unicode grapheme clusters. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ else
+ {
+ int lgb, rgb;
+ GETCHARINCTEST(c, eptr);
+ lgb = UCD_GRAPHBREAK(c);
+ while (eptr < mb->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ rgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ lgb = rgb;
+ eptr += len;
+ }
+ }
+ CHECK_PARTIAL();
+ }
+
+ /* eptr is now past the end of the maximum run */
+
+ if (possessive) continue; /* No backtracking */
+
+ /* We use <= pp rather than == pp to detect the start of the run while
+ backtracking because the use of \C in UTF mode can cause BACKCHAR to
+ move back past pp. This is just palliative; the use of \C in UTF mode
+ is fraught with danger. */
+
+ for(;;)
+ {
+ int lgb, rgb;
+ PCRE2_SPTR fptr;
+
+ if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM45);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+
+ /* Backtracking over an extended grapheme cluster involves inspecting
+ the previous two characters (if present) to see if a break is
+ permitted between them. */
+
+ eptr--;
+ if (!utf) c = *eptr; else
+ {
+ BACKCHAR(eptr);
+ GETCHAR(c, eptr);
+ }
+ rgb = UCD_GRAPHBREAK(c);
+
+ for (;;)
+ {
+ if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */
+ fptr = eptr - 1;
+ if (!utf) c = *fptr; else
+ {
+ BACKCHAR(fptr);
+ GETCHAR(c, fptr);
+ }
+ lgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ eptr = fptr;
+ rgb = lgb;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UNICODE */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ switch(ctype)
+ {
+ case OP_ANY:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ if (mb->partial != 0 && /* Take care with CRLF partial */
+ eptr + 1 >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ UCHAR21(eptr) == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ eptr++;
+ ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_ALLANY:
+ if (max < INT_MAX)
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ eptr++;
+ ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+ }
+ }
+ else
+ {
+ eptr = mb->end_subject; /* Unlimited UTF-8 repeat */
+ SCHECK_PARTIAL();
+ }
+ break;
+
+ /* The byte case is the same as non-UTF8 */
+
+ case OP_ANYBYTE:
+ c = max - min;
+ if (c > (uint32_t)(mb->end_subject - eptr))
+ {
+ eptr = mb->end_subject;
+ SCHECK_PARTIAL();
+ }
+ else eptr += c;
+ break;
+
+ case OP_ANYNL:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c == CHAR_CR)
+ {
+ if (++eptr >= mb->end_subject) break;
+ if (UCHAR21(eptr) == CHAR_LF) eptr++;
+ }
+ else
+ {
+ if (c != CHAR_LF &&
+ (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
+ (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
+#ifndef EBCDIC
+ && c != 0x2028 && c != 0x2029
+#endif /* Not EBCDIC */
+ )))
+ break;
+ eptr += len;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ BOOL gotspace;
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ switch(c)
+ {
+ HSPACE_CASES: gotspace = TRUE; break;
+ default: gotspace = FALSE; break;
+ }
+ if (gotspace == (ctype == OP_NOT_HSPACE)) break;
+ eptr += len;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ BOOL gotspace;
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ switch(c)
+ {
+ VSPACE_CASES: gotspace = TRUE; break;
+ default: gotspace = FALSE; break;
+ }
+ if (gotspace == (ctype == OP_NOT_VSPACE)) break;
+ eptr += len;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 ||(mb->ctypes[c] & ctype_digit) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (mb->ctypes[c] & ctype_space) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 ||(mb->ctypes[c] & ctype_space) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (mb->ctypes[c] & ctype_word) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+
+ if (possessive) continue; /* No backtracking */
+
+ /* After \C in UTF mode, pp might be in the middle of a Unicode
+ character. Use <= pp to ensure backtracking doesn't go too far. */
+
+ for(;;)
+ {
+ if (eptr <= pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM46);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ BACKCHAR(eptr);
+ if (ctype == OP_ANYNL && eptr > pp && UCHAR21(eptr) == CHAR_NL &&
+ UCHAR21(eptr - 1) == CHAR_CR) eptr--;
+ }
+ }
+ else
+#endif /* SUPPORT_UNICODE */
+ /* Not UTF mode */
+ {
+ switch(ctype)
+ {
+ case OP_ANY:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ if (mb->partial != 0 && /* Take care with CRLF partial */
+ eptr + 1 >= mb->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+ }
+ eptr++;
+ }
+ break;
+
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ c = max - min;
+ if (c > (uint32_t)(mb->end_subject - eptr))
+ {
+ eptr = mb->end_subject;
+ SCHECK_PARTIAL();
+ }
+ else eptr += c;
+ break;
+
+ case OP_ANYNL:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c == CHAR_CR)
+ {
+ if (++eptr >= mb->end_subject) break;
+ if (*eptr == CHAR_LF) eptr++;
+ }
+ else
+ {
+ if (c != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
+ (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ && c != 0x2028 && c != 0x2029
+#endif
+ ))) break;
+ eptr++;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ switch(*eptr)
+ {
+ default: eptr++; break;
+ HSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ HSPACE_MULTIBYTE_CASES:
+#endif
+ goto ENDLOOP00;
+ }
+ }
+ ENDLOOP00:
+ break;
+
+ case OP_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ switch(*eptr)
+ {
+ default: goto ENDLOOP01;
+ HSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ HSPACE_MULTIBYTE_CASES:
+#endif
+ eptr++; break;
+ }
+ }
+ ENDLOOP01:
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ switch(*eptr)
+ {
+ default: eptr++; break;
+ VSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ VSPACE_MULTIBYTE_CASES:
+#endif
+ goto ENDLOOP02;
+ }
+ }
+ ENDLOOP02:
+ break;
+
+ case OP_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ switch(*eptr)
+ {
+ default: goto ENDLOOP03;
+ VSPACE_BYTE_CASES:
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ VSPACE_MULTIBYTE_CASES:
+#endif
+ eptr++; break;
+ }
+ }
+ ENDLOOP03:
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= mb->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0) break;
+ eptr++;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+
+ if (possessive) continue; /* No backtracking */
+ for (;;)
+ {
+ if (eptr == pp) goto TAIL_RECURSE;
+ RMATCH(eptr, ecode, offset_top, mb, eptrb, RM47);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ if (ctype == OP_ANYNL && eptr > pp && *eptr == CHAR_LF &&
+ eptr[-1] == CHAR_CR) eptr--;
+ }
+ }
+
+ /* Control never gets here */
+ }
+
+ /* There's been some horrible disaster. Arrival here can only mean there is
+ something seriously wrong in the code above or the OP_xxx definitions. */
+
+ default:
+ RRETURN(PCRE2_ERROR_INTERNAL);
+ }
+
+ /* Do not stick any code in here without much thought; it is assumed
+ that "continue" in the code above comes out to here to repeat the main
+ loop. */
+
+ } /* End of main loop */
+/* Control never reaches here */
+
+
+/* When compiling to use the heap rather than the stack for recursive calls to
+match(), the RRETURN() macro jumps here. The number that is saved in
+frame->Xwhere indicates which label we actually want to return to. */
+
+#ifdef HEAP_MATCH_RECURSE
+#define LBL(val) case val: goto L_RM##val;
+HEAP_RETURN:
+switch (frame->Xwhere)
+ {
+ LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
+ LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
+ LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
+ LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
+ LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
+ LBL(65) LBL(66) LBL(68)
+#ifdef SUPPORT_WIDE_CHARS
+ LBL(20) LBL(21)
+#endif
+#ifdef SUPPORT_UNICODE
+ LBL(16) LBL(18)
+ LBL(22) LBL(23) LBL(28) LBL(30)
+ LBL(32) LBL(34) LBL(42) LBL(46)
+ LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
+ LBL(59) LBL(60) LBL(61) LBL(62) LBL(67)
+#endif /* SUPPORT_UNICODE */
+ default:
+ return PCRE2_ERROR_INTERNAL;
+ }
+#undef LBL
+#endif /* HEAP_MATCH_RECURSE */
+}
+
+
+/***************************************************************************
+****************************************************************************
+ RECURSION IN THE match() FUNCTION
+
+Undefine all the macros that were defined above to handle this. */
+
+#ifdef HEAP_MATCH_RECURSE
+#undef eptr
+#undef ecode
+#undef mstart
+#undef offset_top
+#undef eptrb
+#undef flags
+
+#undef callpat
+#undef charptr
+#undef data
+#undef next_ecode
+#undef pp
+#undef prev
+#undef saved_eptr
+
+#undef new_recursive
+
+#undef cur_is_word
+#undef condition
+#undef prev_is_word
+
+#undef ctype
+#undef length
+#undef max
+#undef min
+#undef number
+#undef offset
+#undef op
+#undef save_capture_last
+#undef save_offset1
+#undef save_offset2
+#undef save_offset3
+
+#undef newptrb
+#endif /* HEAP_MATCH_RECURSE */
+
+/* These two are defined as macros in both cases */
+
+#undef fc
+#undef fi
+
+/***************************************************************************
+***************************************************************************/
+
+
+#ifdef HEAP_MATCH_RECURSE
+/*************************************************
+* Release allocated heap frames *
+*************************************************/
+
+/* This function releases all the allocated frames. The base frame is on the
+machine stack, and so must not be freed.
+
+Argument:
+ frame_base the address of the base frame
+ mb the match block
+
+Returns: nothing
+*/
+
+static void
+release_match_heapframes (heapframe *frame_base, match_block *mb)
+{
+heapframe *nextframe = frame_base->Xnextframe;
+while (nextframe != NULL)
+ {
+ heapframe *oldframe = nextframe;
+ nextframe = nextframe->Xnextframe;
+ mb->stack_memctl.free(oldframe, mb->stack_memctl.memory_data);
+ }
+}
+#endif /* HEAP_MATCH_RECURSE */
+
+
+
+/*************************************************
+* Match a Regular Expression *
+*************************************************/
+
+/* This function applies a compiled pattern to a subject string and picks out
+portions of the string if it matches. Two elements in the vector are set for
+each substring: the offsets to the start and end of the substring.
+
+Arguments:
+ code points to the compiled expression
+ subject points to the subject string
+ length length of subject string (may contain binary zeros)
+ start_offset where to start in the subject string
+ options option bits
+ match_data points to a match_data block
+ mcontext points a PCRE2 context
+
+Returns: > 0 => success; value is the number of ovector pairs filled
+ = 0 => success, but ovector is not big enough
+ -1 => failed to match (PCRE2_ERROR_NOMATCH)
+ -2 => partial match (PCRE2_ERROR_PARTIAL)
+ < -2 => some kind of unexpected problem
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
+ PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
+ pcre2_match_context *mcontext)
+{
+int rc;
+int ocount;
+
+const uint8_t *start_bits = NULL;
+
+const pcre2_real_code *re = (const pcre2_real_code *)code;
+
+BOOL anchored;
+BOOL firstline;
+BOOL has_first_cu = FALSE;
+BOOL has_req_cu = FALSE;
+BOOL startline;
+BOOL using_temporary_offsets = FALSE;
+BOOL utf;
+
+PCRE2_UCHAR first_cu = 0;
+PCRE2_UCHAR first_cu2 = 0;
+PCRE2_UCHAR req_cu = 0;
+PCRE2_UCHAR req_cu2 = 0;
+
+PCRE2_SPTR bumpalong_limit;
+PCRE2_SPTR end_subject;
+PCRE2_SPTR start_match = subject + start_offset;
+PCRE2_SPTR req_cu_ptr = start_match - 1;
+PCRE2_SPTR start_partial = NULL;
+PCRE2_SPTR match_partial = NULL;
+
+/* We need to have mb pointing to a match block, because the IS_NEWLINE macro
+is used below, and it expects NLBLOCK to be defined as a pointer. */
+
+match_block actual_match_block;
+match_block *mb = &actual_match_block;
+
+#ifdef HEAP_MATCH_RECURSE
+heapframe frame_zero;
+frame_zero.Xprevframe = NULL; /* Marks the top level */
+frame_zero.Xnextframe = NULL; /* None are allocated yet */
+mb->match_frames_base = &frame_zero;
+#endif
+
+/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated
+subject string. */
+
+if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject);
+end_subject = subject + length;
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
+if (code == NULL || subject == NULL || match_data == NULL)
+ return PCRE2_ERROR_NULL;
+if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
+
+/* Check that the first field in the block is the magic number. */
+
+if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+
+/* Check the code unit width. */
+
+if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
+ return PCRE2_ERROR_BADMODE;
+
+/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
+options variable for this function. Users of PCRE2 who are not calling the
+function directly would like to have a way of setting these flags, in the same
+way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with
+constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and
+(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be
+transferred to the options for this function. The bits are guaranteed to be
+adjacent, but do not have the same values. This bit of Boolean trickery assumes
+that the match-time bits are not more significant than the flag bits. If by
+accident this is not the case, a compile-time division by zero error will
+occur. */
+
+#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)
+#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)
+options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
+#undef FF
+#undef OO
+
+/* A NULL match context means "use a default context" */
+
+if (mcontext == NULL)
+ mcontext = (pcre2_match_context *)(&PRIV(default_match_context));
+
+/* These two settings are used in the code for checking a UTF string that
+follows immediately afterwards. Other values in the mb block are used only
+during interpretive pcre_match() processing, not when the JIT support is in
+use, so they are set up later. */
+
+utf = (re->overall_options & PCRE2_UTF) != 0;
+mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 :
+ ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0;
+
+/* Check a UTF string for validity if required. For 8-bit and 16-bit strings,
+we must also check that a starting offset does not point into the middle of a
+multiunit character. We check only the portion of the subject that is going to
+be inspected during matching - from the offset minus the maximum back reference
+to the given length. This saves time when a small part of a large subject is
+being matched by the use of a starting offset. Note that the maximum lookbehind
+is a number of characters, not code units. */
+
+#ifdef SUPPORT_UNICODE
+if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
+ {
+ PCRE2_SPTR check_subject = start_match; /* start_match includes offset */
+
+ if (start_offset > 0)
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ unsigned int i;
+ if (start_match < end_subject && NOT_FIRSTCU(*start_match))
+ return PCRE2_ERROR_BADUTFOFFSET;
+ for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)
+ {
+ check_subject--;
+ while (check_subject > subject &&
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ (*check_subject & 0xc0) == 0x80)
+#else /* 16-bit */
+ (*check_subject & 0xfc00) == 0xdc00)
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+ check_subject--;
+ }
+#else
+ /* In the 32-bit library, one code unit equals one character. However,
+ we cannot just subtract the lookbehind and then compare pointers, because
+ a very large lookbehind could create an invalid pointer. */
+
+ if (start_offset >= re->max_lookbehind)
+ check_subject -= re->max_lookbehind;
+ else
+ check_subject = subject;
+#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
+ }
+
+ /* Validate the relevant portion of the subject. After an error, adjust the
+ offset to be an absolute offset in the whole string. */
+
+ match_data->rc = PRIV(valid_utf)(check_subject,
+ length - (check_subject - subject), &(match_data->startchar));
+ if (match_data->rc != 0)
+ {
+ match_data->startchar += check_subject - subject;
+ return match_data->rc;
+ }
+ }
+#endif /* SUPPORT_UNICODE */
+
+/* It is an error to set an offset limit without setting the flag at compile
+time. */
+
+if (mcontext->offset_limit != PCRE2_UNSET &&
+ (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
+ return PCRE2_ERROR_BADOFFSETLIMIT;
+
+/* If the pattern was successfully studied with JIT support, run the JIT
+executable instead of the rest of this function. Most options must be set at
+compile time for the JIT code to be usable. Fallback to the normal code path if
+an unsupported option is set or if JIT returns BADOPTION (which means that the
+selected normal or partial matching mode was not compiled). */
+
+#ifdef SUPPORT_JIT
+if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0)
+ {
+ rc = pcre2_jit_match(code, subject, length, start_offset, options,
+ match_data, mcontext);
+ if (rc != PCRE2_ERROR_JIT_BADOPTION) return rc;
+ }
+#endif
+
+/* Carry on with non-JIT matching. */
+
+anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0;
+firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
+startline = (re->flags & PCRE2_STARTLINE) != 0;
+bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?
+ end_subject : subject + mcontext->offset_limit;
+
+/* Fill in the fields in the match block. */
+
+mb->callout = mcontext->callout;
+mb->callout_data = mcontext->callout_data;
+mb->memctl = mcontext->memctl;
+#ifdef HEAP_MATCH_RECURSE
+mb->stack_memctl = mcontext->stack_memctl;
+#endif
+
+mb->start_subject = subject;
+mb->start_offset = start_offset;
+mb->end_subject = end_subject;
+mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;
+
+mb->moptions = options; /* Match options */
+mb->poptions = re->overall_options; /* Pattern options */
+
+mb->ignore_skip_arg = 0;
+mb->mark = mb->nomatch_mark = NULL; /* In case never set */
+mb->recursive = NULL; /* No recursion at top level */
+mb->ovecsave_chain = NULL; /* No ovecsave blocks yet */
+mb->hitend = FALSE;
+
+/* The name table is needed for finding all the numbers associated with a
+given name, for condition testing. The code follows the name table. */
+
+mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));
+mb->name_count = re->name_count;
+mb->name_entry_size = re->name_entry_size;
+mb->start_code = mb->name_table + re->name_count * re->name_entry_size;
+
+/* Limits set in the pattern override the match context only if they are
+smaller. */
+
+mb->match_limit = (mcontext->match_limit < re->limit_match)?
+ mcontext->match_limit : re->limit_match;
+mb->match_limit_recursion = (mcontext->recursion_limit < re->limit_recursion)?
+ mcontext->recursion_limit : re->limit_recursion;
+
+/* Pointers to the individual character tables */
+
+mb->lcc = re->tables + lcc_offset;
+mb->fcc = re->tables + fcc_offset;
+mb->ctypes = re->tables + ctypes_offset;
+
+/* Process the \R and newline settings. */
+
+mb->bsr_convention = re->bsr_convention;
+mb->nltype = NLTYPE_FIXED;
+switch(re->newline_convention)
+ {
+ case PCRE2_NEWLINE_CR:
+ mb->nllen = 1;
+ mb->nl[0] = CHAR_CR;
+ break;
+
+ case PCRE2_NEWLINE_LF:
+ mb->nllen = 1;
+ mb->nl[0] = CHAR_NL;
+ break;
+
+ case PCRE2_NEWLINE_CRLF:
+ mb->nllen = 2;
+ mb->nl[0] = CHAR_CR;
+ mb->nl[1] = CHAR_NL;
+ break;
+
+ case PCRE2_NEWLINE_ANY:
+ mb->nltype = NLTYPE_ANY;
+ break;
+
+ case PCRE2_NEWLINE_ANYCRLF:
+ mb->nltype = NLTYPE_ANYCRLF;
+ break;
+
+ default: return PCRE2_ERROR_INTERNAL;
+ }
+
+/* If the expression has got more back references than the offsets supplied can
+hold, we get a temporary chunk of memory to use during the matching. Otherwise,
+we can use the vector supplied. The size of the ovector is three times the
+value in the oveccount field. Two-thirds of it is pairs for storing matching
+offsets, and the top third is working space. */
+
+if (re->top_backref >= match_data->oveccount)
+ {
+ ocount = re->top_backref * 3 + 3;
+ mb->ovector = (PCRE2_SIZE *)(mb->memctl.malloc(ocount * sizeof(PCRE2_SIZE),
+ mb->memctl.memory_data));
+ if (mb->ovector == NULL) return PCRE2_ERROR_NOMEMORY;
+ using_temporary_offsets = TRUE;
+ }
+else
+ {
+ ocount = 3 * match_data->oveccount;
+ mb->ovector = match_data->ovector;
+ }
+
+mb->offset_end = ocount;
+mb->offset_max = (2*ocount)/3;
+
+/* Reset the working variable associated with each extraction. These should
+never be used unless previously set, but they get saved and restored, and so we
+initialize them to avoid reading uninitialized locations. Also, unset the
+offsets for the matched string. This is really just for tidiness with callouts,
+in case they inspect these fields. */
+
+if (ocount > 0)
+ {
+ PCRE2_SIZE *iptr = mb->ovector + ocount;
+ PCRE2_SIZE *iend = iptr - re->top_bracket;
+ if (iend < mb->ovector + 2) iend = mb->ovector + 2;
+ while (--iptr >= iend) *iptr = PCRE2_UNSET;
+ mb->ovector[0] = mb->ovector[1] = PCRE2_UNSET;
+ }
+
+/* Set up the first code unit to match, if available. The first_codeunit value
+is never set for an anchored regular expression, but the anchoring may be
+forced at run time, so we have to test for anchoring. The first code unit may
+be unset for an unanchored pattern, of course. If there's no first code unit
+there may be a bitmap of possible first characters. */
+
+if (!anchored)
+ {
+ if ((re->flags & PCRE2_FIRSTSET) != 0)
+ {
+ has_first_cu = TRUE;
+ first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
+ if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
+ {
+ first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu);
+#endif
+ }
+ }
+ else
+ if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
+ start_bits = re->start_bitmap;
+ }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE2_LASTSET) != 0)
+ {
+ has_req_cu = TRUE;
+ req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);
+ if ((re->flags & PCRE2_LASTCASELESS) != 0)
+ {
+ req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+ if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu);
+#endif
+ }
+ }
+
+
+/* ==========================================================================*/
+
+/* Loop for handling unanchored repeated matching attempts; for anchored regexs
+the loop runs just once. */
+
+for(;;)
+ {
+ PCRE2_SPTR new_start_match;
+ mb->capture_last = 0;
+
+ /* ----------------- Start of match optimizations ---------------- */
+
+ /* There are some optimizations that avoid running the match if a known
+ starting point is not found, or if a known later code unit is not present.
+ However, there is an option (settable at compile time) that disables these,
+ for testing and for ensuring that all callouts do actually occur. */
+
+ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
+ {
+ PCRE2_SPTR save_end_subject = end_subject;
+
+ /* If firstline is TRUE, the start of the match is constrained to the first
+ line of a multiline string. That is, the match must be before or at the
+ first newline. Implement this by temporarily adjusting end_subject so that
+ we stop the optimization scans at a newline. If the match fails at the
+ newline, later code breaks this loop. */
+
+ if (firstline)
+ {
+ PCRE2_SPTR t = start_match;
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ while (t < mb->end_subject && !IS_NEWLINE(t))
+ {
+ t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
+ }
+ }
+ else
+#endif
+ while (t < mb->end_subject && !IS_NEWLINE(t)) t++;
+ end_subject = t;
+ }
+
+ /* Advance to a unique first code unit if there is one. In 8-bit mode, the
+ use of memchr() gives a big speed up. */
+
+ if (has_first_cu)
+ {
+ PCRE2_UCHAR smc;
+ if (first_cu != first_cu2)
+ while (start_match < end_subject &&
+ (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2)
+ start_match++;
+ else
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu)
+ start_match++;
+#else
+ start_match = memchr(start_match, first_cu, end_subject - start_match);
+ if (start_match == NULL) start_match = end_subject;
+#endif
+ }
+ }
+
+ /* Or to just after a linebreak for a multiline match */
+
+ else if (startline)
+ {
+ if (start_match > mb->start_subject + start_offset)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ {
+ start_match++;
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
+ }
+ }
+ else
+#endif
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ start_match++;
+
+ /* If we have just passed a CR and the newline option is ANY or
+ ANYCRLF, and we are now at a LF, advance the match position by one more
+ code unit. */
+
+ if (start_match[-1] == CHAR_CR &&
+ (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
+ start_match < end_subject &&
+ UCHAR21TEST(start_match) == CHAR_NL)
+ start_match++;
+ }
+ }
+
+ /* Or to a non-unique first code unit if any have been identified. The
+ bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all
+ code units greater than 254 set the 255 bit. */
+
+ else if (start_bits != NULL)
+ {
+ while (start_match < end_subject)
+ {
+ uint32_t c = UCHAR21TEST(start_match);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ if (c > 255) c = 255;
+#endif
+ if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
+ start_match++;
+ }
+ }
+
+ /* Restore fudged end_subject */
+
+ end_subject = save_end_subject;
+
+ /* The following two optimizations are disabled for partial matching. */
+
+ if (!mb->partial)
+ {
+ /* The minimum matching length is a lower bound; no actual string of that
+ length may actually match the pattern. Although the value is, strictly,
+ in characters, we treat it as code units to avoid spending too much time
+ in this optimization. */
+
+ if (end_subject - start_match < re->minlength)
+ {
+ rc = MATCH_NOMATCH;
+ break;
+ }
+
+ /* If req_cu is set, we know that that code unit must appear in the
+ subject for the match to succeed. If the first code unit is set, req_cu
+ must be later in the subject; otherwise the test starts at the match
+ point. This optimization can save a huge amount of backtracking in
+ patterns with nested unlimited repeats that aren't going to match.
+ Writing separate code for cased/caseless versions makes it go faster, as
+ does using an autoincrement and backing off on a match.
+
+ HOWEVER: when the subject string is very, very long, searching to its end
+ can take a long time, and give bad performance on quite ordinary
+ patterns. This showed up when somebody was matching something like
+ /^\d+C/ on a 32-megabyte string... so we don't do this when the string is
+ sufficiently long. */
+
+ if (has_req_cu && end_subject - start_match < REQ_CU_MAX)
+ {
+ PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
+
+ /* We don't need to repeat the search if we haven't yet reached the
+ place we found it at last time. */
+
+ if (p > req_cu_ptr)
+ {
+ if (req_cu != req_cu2)
+ {
+ while (p < end_subject)
+ {
+ uint32_t pp = UCHAR21INCTEST(p);
+ if (pp == req_cu || pp == req_cu2) { p--; break; }
+ }
+ }
+ else
+ {
+ while (p < end_subject)
+ {
+ if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
+ }
+ }
+
+ /* If we can't find the required code unit, break the matching loop,
+ forcing a match failure. */
+
+ if (p >= end_subject)
+ {
+ rc = MATCH_NOMATCH;
+ break;
+ }
+
+ /* If we have found the required code unit, save the point where we
+ found it, so that we don't search again next time round the loop if
+ the start hasn't passed this code unit yet. */
+
+ req_cu_ptr = p;
+ }
+ }
+ }
+ }
+
+ /* ------------ End of start of match optimizations ------------ */
+
+ /* Give no match if we have passed the bumpalong limit. */
+
+ if (start_match > bumpalong_limit)
+ {
+ rc = MATCH_NOMATCH;
+ break;
+ }
+
+ /* OK, we can now run the match. If "hitend" is set afterwards, remember the
+ first starting point for which a partial match was found. */
+
+ mb->start_match_ptr = start_match;
+ mb->start_used_ptr = start_match;
+ mb->last_used_ptr = start_match;
+ mb->match_call_count = 0;
+ mb->match_function_type = 0;
+ mb->end_offset_top = 0;
+ mb->skip_arg_count = 0;
+ rc = match(start_match, mb->start_code, start_match, 2, mb, NULL, 0);
+
+ if (mb->hitend && start_partial == NULL)
+ {
+ start_partial = mb->start_used_ptr;
+ match_partial = start_match;
+ }
+
+ switch(rc)
+ {
+ /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
+ the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
+ entirely. The only way we can do that is to re-do the match at the same
+ point, with a flag to force SKIP with an argument to be ignored. Just
+ treating this case as NOMATCH does not work because it does not check other
+ alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
+
+ case MATCH_SKIP_ARG:
+ new_start_match = start_match;
+ mb->ignore_skip_arg = mb->skip_arg_count;
+ break;
+
+ /* SKIP passes back the next starting point explicitly, but if it is no
+ greater than the match we have just done, treat it as NOMATCH. */
+
+ case MATCH_SKIP:
+ if (mb->start_match_ptr > start_match)
+ {
+ new_start_match = mb->start_match_ptr;
+ break;
+ }
+ /* Fall through */
+
+ /* NOMATCH and PRUNE advance by one character. THEN at this level acts
+ exactly like PRUNE. Unset ignore SKIP-with-argument. */
+
+ case MATCH_NOMATCH:
+ case MATCH_PRUNE:
+ case MATCH_THEN:
+ mb->ignore_skip_arg = 0;
+ new_start_match = start_match + 1;
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ ACROSSCHAR(new_start_match < end_subject, *new_start_match,
+ new_start_match++);
+#endif
+ break;
+
+ /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
+
+ case MATCH_COMMIT:
+ rc = MATCH_NOMATCH;
+ goto ENDLOOP;
+
+ /* Any other return is either a match, or some kind of error. */
+
+ default:
+ goto ENDLOOP;
+ }
+
+ /* Control reaches here for the various types of "no match at this point"
+ result. Reset the code to MATCH_NOMATCH for subsequent checking. */
+
+ rc = MATCH_NOMATCH;
+
+ /* If PCRE2_FIRSTLINE is set, the match must happen before or at the first
+ newline in the subject (though it may continue over the newline). Therefore,
+ if we have just failed to match, starting at a newline, do not continue. */
+
+ if (firstline && IS_NEWLINE(start_match)) break;
+
+ /* Advance to new matching position */
+
+ start_match = new_start_match;
+
+ /* Break the loop if the pattern is anchored or if we have passed the end of
+ the subject. */
+
+ if (anchored || start_match > end_subject) break;
+
+ /* If we have just passed a CR and we are now at a LF, and the pattern does
+ not contain any explicit matches for \r or \n, and the newline option is CRLF
+ or ANY or ANYCRLF, advance the match position by one more code unit. In
+ normal matching start_match will aways be greater than the first position at
+ this stage, but a failed *SKIP can cause a return at the same point, which is
+ why the first test exists. */
+
+ if (start_match > subject + start_offset &&
+ start_match[-1] == CHAR_CR &&
+ start_match < end_subject &&
+ *start_match == CHAR_NL &&
+ (re->flags & PCRE2_HASCRORLF) == 0 &&
+ (mb->nltype == NLTYPE_ANY ||
+ mb->nltype == NLTYPE_ANYCRLF ||
+ mb->nllen == 2))
+ start_match++;
+
+ mb->mark = NULL; /* Reset for start of next match attempt */
+ } /* End of for(;;) "bumpalong" loop */
+
+/* ==========================================================================*/
+
+/* When we reach here, one of the stopping conditions is true:
+
+(1) The match succeeded, either completely, or partially;
+
+(2) The pattern is anchored or the match was failed by (*COMMIT);
+
+(3) We are past the end of the subject or the bumpalong limit;
+
+(4) PCRE2_FIRSTLINE is set and we have failed to match at a newline, because
+ this option requests that a match occur at or before the first newline in
+ the subject.
+
+(5) Some kind of error occurred.
+
+*/
+
+ENDLOOP:
+
+#ifdef HEAP_MATCH_RECURSE
+release_match_heapframes(&frame_zero, mb);
+#endif
+
+/* Release any frames that were saved from recursions. */
+
+while (mb->ovecsave_chain != NULL)
+ {
+ ovecsave_frame *this = mb->ovecsave_chain;
+ mb->ovecsave_chain = this->next;
+ mb->memctl.free(this, mb->memctl.memory_data);
+ }
+
+/* Fill in fields that are always returned in the match data. */
+
+match_data->code = re;
+match_data->subject = subject;
+match_data->mark = mb->mark;
+match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER;
+
+/* Handle a fully successful match. */
+
+if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
+ {
+ uint32_t arg_offset_max = 2 * match_data->oveccount;
+
+ /* When the offset vector is big enough to deal with any backreferences,
+ captured substring offsets will already be set up. In the case where we had
+ to get some local memory to hold offsets for backreference processing, copy
+ those that we can. In this case there need not be overflow if certain parts
+ of the pattern were not used, even though there are more capturing
+ parentheses than vector slots. */
+
+ if (using_temporary_offsets)
+ {
+ if (arg_offset_max >= 4)
+ {
+ memcpy(match_data->ovector + 2, mb->ovector + 2,
+ (arg_offset_max - 2) * sizeof(PCRE2_SIZE));
+ }
+ if (mb->end_offset_top > arg_offset_max) mb->capture_last |= OVFLBIT;
+ mb->memctl.free(mb->ovector, mb->memctl.memory_data);
+ }
+
+ /* Set the return code to the number of captured strings, or 0 if there were
+ too many to fit into the ovector. */
+
+ match_data->rc = ((mb->capture_last & OVFLBIT) != 0)?
+ 0 : (int)mb->end_offset_top/2;
+
+ /* If there is space in the offset vector, set any pairs that follow the
+ highest-numbered captured string but are less than the number of capturing
+ groups in the pattern (and are within the ovector) to PCRE2_UNSET. It is
+ documented that this happens. In earlier versions, the whole set of potential
+ capturing offsets was initialized each time round the loop, but this is
+ handled differently now. "Gaps" are set to PCRE2_UNSET dynamically instead
+ (this fixed a bug). Thus, it is only those at the end that need setting here.
+ We can't just mark them all unset at the start of the whole thing because
+ they may get set in one branch that is not the final matching branch. */
+
+ if (mb->end_offset_top/2 <= re->top_bracket)
+ {
+ PCRE2_SIZE *iptr, *iend;
+ int resetcount = re->top_bracket + 1;
+ if (resetcount > match_data->oveccount) resetcount = match_data->oveccount;
+ iptr = match_data->ovector + mb->end_offset_top;
+ iend = match_data->ovector + 2 * resetcount;
+ while (iptr < iend) *iptr++ = PCRE2_UNSET;
+ }
+
+ /* If there is space, set up the whole thing as substring 0. The value of
+ mb->start_match_ptr might be modified if \K was encountered on the success
+ matching path. */
+
+ if (match_data->oveccount < 1) rc = 0; else
+ {
+ match_data->ovector[0] = mb->start_match_ptr - mb->start_subject;
+ match_data->ovector[1] = mb->end_match_ptr - mb->start_subject;
+ }
+
+ /* Set the remaining returned values */
+
+ match_data->startchar = start_match - subject;
+ match_data->leftchar = mb->start_used_ptr - subject;
+ match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?
+ mb->last_used_ptr : mb->end_match_ptr) - subject;
+ return match_data->rc;
+ }
+
+/* Control gets here if there has been a partial match, an error, or if the
+overall match attempt has failed at all permitted starting positions. Any mark
+data is in the nomatch_mark field. */
+
+match_data->mark = mb->nomatch_mark;
+
+/* For anything other than nomatch or partial match, just return the code. */
+
+if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL)
+ match_data->rc = rc;
+
+/* Else handle a partial match. */
+
+else if (match_partial != NULL)
+ {
+ if (match_data->oveccount > 0)
+ {
+ match_data->ovector[0] = match_partial - subject;
+ match_data->ovector[1] = end_subject - subject;
+ }
+ match_data->startchar = match_partial - subject;
+ match_data->leftchar = start_partial - subject;
+ match_data->rightchar = end_subject - subject;
+ match_data->rc = PCRE2_ERROR_PARTIAL;
+ }
+
+/* Else this is the classic nomatch case. */
+
+else match_data->rc = PCRE2_ERROR_NOMATCH;
+
+/* Free any temporary offsets. */
+
+if (using_temporary_offsets)
+ mb->memctl.free(mb->ovector, mb->memctl.memory_data);
+return match_data->rc;
+}
+
+/* End of pcre2_match.c */
diff --git a/thirdparty/pcre2/src/pcre2_match_data.c b/thirdparty/pcre2/src/pcre2_match_data.c
new file mode 100644
index 0000000000..85ac998348
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_match_data.c
@@ -0,0 +1,147 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+
+/*************************************************
+* Create a match data block given ovector size *
+*************************************************/
+
+/* A minimum of 1 is imposed on the number of ovector triplets. */
+
+PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION
+pcre2_match_data_create(uint32_t oveccount, pcre2_general_context *gcontext)
+{
+pcre2_match_data *yield;
+if (oveccount < 1) oveccount = 1;
+yield = PRIV(memctl_malloc)(
+ sizeof(pcre2_match_data) + 3*oveccount*sizeof(PCRE2_SIZE),
+ (pcre2_memctl *)gcontext);
+if (yield == NULL) return NULL;
+yield->oveccount = oveccount;
+return yield;
+}
+
+
+
+/*************************************************
+* Create a match data block using pattern data *
+*************************************************/
+
+/* If no context is supplied, use the memory allocator from the code. */
+
+PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION
+pcre2_match_data_create_from_pattern(const pcre2_code *code,
+ pcre2_general_context *gcontext)
+{
+if (gcontext == NULL) gcontext = (pcre2_general_context *)code;
+return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1,
+ gcontext);
+}
+
+
+
+/*************************************************
+* Free a match data block *
+*************************************************/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_match_data_free(pcre2_match_data *match_data)
+{
+if (match_data != NULL)
+ match_data->memctl.free(match_data, match_data->memctl.memory_data);
+}
+
+
+
+/*************************************************
+* Get last mark in match *
+*************************************************/
+
+PCRE2_EXP_DEFN PCRE2_SPTR PCRE2_CALL_CONVENTION
+pcre2_get_mark(pcre2_match_data *match_data)
+{
+return match_data->mark;
+}
+
+
+
+/*************************************************
+* Get pointer to ovector *
+*************************************************/
+
+PCRE2_EXP_DEFN PCRE2_SIZE * PCRE2_CALL_CONVENTION
+pcre2_get_ovector_pointer(pcre2_match_data *match_data)
+{
+return match_data->ovector;
+}
+
+
+
+/*************************************************
+* Get number of ovector slots *
+*************************************************/
+
+PCRE2_EXP_DEFN uint32_t PCRE2_CALL_CONVENTION
+pcre2_get_ovector_count(pcre2_match_data *match_data)
+{
+return match_data->oveccount;
+}
+
+
+
+/*************************************************
+* Get starting code unit in match *
+*************************************************/
+
+PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION
+pcre2_get_startchar(pcre2_match_data *match_data)
+{
+return match_data->startchar;
+}
+
+/* End of pcre2_match_data.c */
diff --git a/thirdparty/pcre2/src/pcre2_newline.c b/thirdparty/pcre2/src/pcre2_newline.c
new file mode 100644
index 0000000000..6e9366db93
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_newline.c
@@ -0,0 +1,243 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains internal functions for testing newlines when more than
+one kind of newline is to be recognized. When a newline is found, its length is
+returned. In principle, we could implement several newline "types", each
+referring to a different set of newline characters. At present, PCRE2 supports
+only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
+and NLTYPE_ANY. The full list of Unicode newline characters is taken from
+http://unicode.org/unicode/reports/tr18/. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+
+/*************************************************
+* Check for newline at given position *
+*************************************************/
+
+/* This function is called only via the IS_NEWLINE macro, which does so only
+when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed
+newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the code unit
+pointed to by ptr is less than the end of the string.
+
+Arguments:
+ ptr pointer to possible newline
+ type the newline type
+ endptr pointer to the end of the string
+ lenptr where to return the length
+ utf TRUE if in utf mode
+
+Returns: TRUE or FALSE
+*/
+
+BOOL
+PRIV(is_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR endptr,
+ uint32_t *lenptr, BOOL utf)
+{
+uint32_t c;
+
+#ifdef SUPPORT_UNICODE
+if (utf) { GETCHAR(c, ptr); } else c = *ptr;
+#else
+(void)utf;
+c = *ptr;
+#endif /* SUPPORT_UNICODE */
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+ {
+ case CHAR_LF:
+ *lenptr = 1;
+ return TRUE;
+
+ case CHAR_CR:
+ *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+
+/* NLTYPE_ANY */
+
+else switch(c)
+ {
+#ifdef EBCDIC
+ case CHAR_NEL:
+#endif
+ case CHAR_LF:
+ case CHAR_VT:
+ case CHAR_FF:
+ *lenptr = 1;
+ return TRUE;
+
+ case CHAR_CR:
+ *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
+ return TRUE;
+
+#ifndef EBCDIC
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ case CHAR_NEL:
+ *lenptr = utf? 2 : 1;
+ return TRUE;
+
+ case 0x2028: /* LS */
+ case 0x2029: /* PS */
+ *lenptr = 3;
+ return TRUE;
+
+#else /* 16-bit or 32-bit code units */
+ case CHAR_NEL:
+ case 0x2028: /* LS */
+ case 0x2029: /* PS */
+ *lenptr = 1;
+ return TRUE;
+#endif
+#endif /* Not EBCDIC */
+
+ default:
+ return FALSE;
+ }
+}
+
+
+
+/*************************************************
+* Check for newline at previous position *
+*************************************************/
+
+/* This function is called only via the WAS_NEWLINE macro, which does so only
+when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed
+newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the initial
+value of ptr is greater than the start of the string that is being processed.
+
+Arguments:
+ ptr pointer to possible newline
+ type the newline type
+ startptr pointer to the start of the string
+ lenptr where to return the length
+ utf TRUE if in utf mode
+
+Returns: TRUE or FALSE
+*/
+
+BOOL
+PRIV(was_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR startptr,
+ uint32_t *lenptr, BOOL utf)
+{
+uint32_t c;
+ptr--;
+
+#ifdef SUPPORT_UNICODE
+if (utf)
+ {
+ BACKCHAR(ptr);
+ GETCHAR(c, ptr);
+ }
+else c = *ptr;
+#else
+(void)utf;
+c = *ptr;
+#endif /* SUPPORT_UNICODE */
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+ {
+ case CHAR_LF:
+ *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
+ return TRUE;
+
+ case CHAR_CR:
+ *lenptr = 1;
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+
+/* NLTYPE_ANY */
+
+else switch(c)
+ {
+ case CHAR_LF:
+ *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
+ return TRUE;
+
+#ifdef EBCDIC
+ case CHAR_NEL:
+#endif
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_CR:
+ *lenptr = 1;
+ return TRUE;
+
+#ifndef EBCDIC
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ case CHAR_NEL:
+ *lenptr = utf? 2 : 1;
+ return TRUE;
+
+ case 0x2028: /* LS */
+ case 0x2029: /* PS */
+ *lenptr = 3;
+ return TRUE;
+
+#else /* 16-bit or 32-bit code units */
+ case CHAR_NEL:
+ case 0x2028: /* LS */
+ case 0x2029: /* PS */
+ *lenptr = 1;
+ return TRUE;
+#endif
+#endif /* Not EBCDIC */
+
+ default:
+ return FALSE;
+ }
+}
+
+/* End of pcre2_newline.c */
diff --git a/thirdparty/pcre2/src/pcre2_ord2utf.c b/thirdparty/pcre2/src/pcre2_ord2utf.c
new file mode 100644
index 0000000000..1403730996
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_ord2utf.c
@@ -0,0 +1,120 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a function that converts a Unicode character code point
+into a UTF string. The behaviour is different for each code unit width. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+/* If SUPPORT_UNICODE is not defined, this function will never be called.
+Supply a dummy function because some compilers do not like empty source
+modules. */
+
+#ifndef SUPPORT_UNICODE
+unsigned int
+PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)
+{
+(void)(cvalue);
+(void)(buffer);
+return 0;
+}
+#else /* SUPPORT_UNICODE */
+
+
+/*************************************************
+* Convert code point to UTF *
+*************************************************/
+
+/*
+Arguments:
+ cvalue the character value
+ buffer pointer to buffer for result
+
+Returns: number of code units placed in the buffer
+*/
+
+unsigned int
+PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)
+{
+/* Convert to UTF-8 */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+int i, j;
+for (i = 0; i < PRIV(utf8_table1_size); i++)
+ if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
+buffer += i;
+for (j = i; j > 0; j--)
+ {
+ *buffer-- = 0x80 | (cvalue & 0x3f);
+ cvalue >>= 6;
+ }
+*buffer = PRIV(utf8_table2)[i] | cvalue;
+return i + 1;
+
+/* Convert to UTF-16 */
+
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+if (cvalue <= 0xffff)
+ {
+ *buffer = (PCRE2_UCHAR)cvalue;
+ return 1;
+ }
+cvalue -= 0x10000;
+*buffer++ = 0xd800 | (cvalue >> 10);
+*buffer = 0xdc00 | (cvalue & 0x3ff);
+return 2;
+
+/* Convert to UTF-32 */
+
+#else
+*buffer = (PCRE2_UCHAR)cvalue;
+return 1;
+#endif
+}
+#endif /* SUPPORT_UNICODE */
+
+/* End of pcre_ord2utf.c */
diff --git a/thirdparty/pcre2/src/pcre2_pattern_info.c b/thirdparty/pcre2/src/pcre2_pattern_info.c
new file mode 100644
index 0000000000..5b32a905b0
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_pattern_info.c
@@ -0,0 +1,410 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+/*************************************************
+* Return info about compiled pattern *
+*************************************************/
+
+/*
+Arguments:
+ code points to compiled code
+ what what information is required
+ where where to put the information; if NULL, return length
+
+Returns: 0 when data returned
+ > 0 when length requested
+ < 0 on error or unset value
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where)
+{
+const pcre2_real_code *re = (pcre2_real_code *)code;
+
+if (where == NULL) /* Requests field length */
+ {
+ switch(what)
+ {
+ case PCRE2_INFO_ALLOPTIONS:
+ case PCRE2_INFO_ARGOPTIONS:
+ case PCRE2_INFO_BACKREFMAX:
+ case PCRE2_INFO_BSR:
+ case PCRE2_INFO_CAPTURECOUNT:
+ case PCRE2_INFO_FIRSTCODETYPE:
+ case PCRE2_INFO_FIRSTCODEUNIT:
+ case PCRE2_INFO_HASBACKSLASHC:
+ case PCRE2_INFO_HASCRORLF:
+ case PCRE2_INFO_JCHANGED:
+ case PCRE2_INFO_LASTCODETYPE:
+ case PCRE2_INFO_LASTCODEUNIT:
+ case PCRE2_INFO_MATCHEMPTY:
+ case PCRE2_INFO_MATCHLIMIT:
+ case PCRE2_INFO_MAXLOOKBEHIND:
+ case PCRE2_INFO_MINLENGTH:
+ case PCRE2_INFO_NAMEENTRYSIZE:
+ case PCRE2_INFO_NAMECOUNT:
+ case PCRE2_INFO_NEWLINE:
+ case PCRE2_INFO_RECURSIONLIMIT:
+ return sizeof(uint32_t);
+
+ case PCRE2_INFO_FIRSTBITMAP:
+ return sizeof(const uint8_t *);
+
+ case PCRE2_INFO_JITSIZE:
+ case PCRE2_INFO_SIZE:
+ return sizeof(size_t);
+
+ case PCRE2_INFO_NAMETABLE:
+ return sizeof(PCRE2_SPTR);
+ }
+ }
+
+if (re == NULL) return PCRE2_ERROR_NULL;
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE2_ERROR_BADMAGIC. */
+
+if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+
+/* Check that this pattern was compiled in the correct bit mode */
+
+if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
+
+switch(what)
+ {
+ case PCRE2_INFO_ALLOPTIONS:
+ *((uint32_t *)where) = re->overall_options;
+ break;
+
+ case PCRE2_INFO_ARGOPTIONS:
+ *((uint32_t *)where) = re->compile_options;
+ break;
+
+ case PCRE2_INFO_BACKREFMAX:
+ *((uint32_t *)where) = re->top_backref;
+ break;
+
+ case PCRE2_INFO_BSR:
+ *((uint32_t *)where) = re->bsr_convention;
+ break;
+
+ case PCRE2_INFO_CAPTURECOUNT:
+ *((uint32_t *)where) = re->top_bracket;
+ break;
+
+ case PCRE2_INFO_FIRSTCODETYPE:
+ *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 :
+ ((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0;
+ break;
+
+ case PCRE2_INFO_FIRSTCODEUNIT:
+ *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)?
+ re->first_codeunit : 0;
+ break;
+
+ case PCRE2_INFO_FIRSTBITMAP:
+ *((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)?
+ &(re->start_bitmap[0]) : NULL;
+ break;
+
+ case PCRE2_INFO_HASBACKSLASHC:
+ *((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0;
+ break;
+
+ case PCRE2_INFO_HASCRORLF:
+ *((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0;
+ break;
+
+ case PCRE2_INFO_JCHANGED:
+ *((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0;
+ break;
+
+ case PCRE2_INFO_JITSIZE:
+#ifdef SUPPORT_JIT
+ *((size_t *)where) = (re->executable_jit != NULL)?
+ PRIV(jit_get_size)(re->executable_jit) : 0;
+#else
+ *((size_t *)where) = 0;
+#endif
+ break;
+
+ case PCRE2_INFO_LASTCODETYPE:
+ *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0;
+ break;
+
+ case PCRE2_INFO_LASTCODEUNIT:
+ *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)?
+ re->last_codeunit : 0;
+ break;
+
+ case PCRE2_INFO_MATCHEMPTY:
+ *((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0;
+ break;
+
+ case PCRE2_INFO_MATCHLIMIT:
+ *((uint32_t *)where) = re->limit_match;
+ if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET;
+ break;
+
+ case PCRE2_INFO_MAXLOOKBEHIND:
+ *((uint32_t *)where) = re->max_lookbehind;
+ break;
+
+ case PCRE2_INFO_MINLENGTH:
+ *((uint32_t *)where) = re->minlength;
+ break;
+
+ case PCRE2_INFO_NAMEENTRYSIZE:
+ *((uint32_t *)where) = re->name_entry_size;
+ break;
+
+ case PCRE2_INFO_NAMECOUNT:
+ *((uint32_t *)where) = re->name_count;
+ break;
+
+ case PCRE2_INFO_NAMETABLE:
+ *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((char *)re + sizeof(pcre2_real_code));
+ break;
+
+ case PCRE2_INFO_NEWLINE:
+ *((uint32_t *)where) = re->newline_convention;
+ break;
+
+ case PCRE2_INFO_RECURSIONLIMIT:
+ *((uint32_t *)where) = re->limit_recursion;
+ if (re->limit_recursion == UINT32_MAX) return PCRE2_ERROR_UNSET;
+ break;
+
+ case PCRE2_INFO_SIZE:
+ *((size_t *)where) = re->blocksize;
+ break;
+
+ default: return PCRE2_ERROR_BADOPTION;
+ }
+
+return 0;
+}
+
+
+
+/*************************************************
+* Callout enumerator *
+*************************************************/
+
+/*
+Arguments:
+ code points to compiled code
+ callback function called for each callout block
+ callout_data user data passed to the callback
+
+Returns: 0 when successfully completed
+ < 0 on local error
+ != 0 for callback error
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_callout_enumerate(const pcre2_code *code,
+ int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data)
+{
+pcre2_real_code *re = (pcre2_real_code *)code;
+pcre2_callout_enumerate_block cb;
+PCRE2_SPTR cc;
+#ifdef SUPPORT_UNICODE
+BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
+#endif
+
+if (re == NULL) return PCRE2_ERROR_NULL;
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE2_ERROR_BADMAGIC. */
+
+if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+
+/* Check that this pattern was compiled in the correct bit mode */
+
+if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
+
+cb.version = 0;
+cc = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code))
+ + re->name_count * re->name_entry_size;
+
+while (TRUE)
+ {
+ int rc;
+ switch (*cc)
+ {
+ case OP_END:
+ return 0;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ cc += PRIV(OP_lengths)[*cc];
+#ifdef SUPPORT_UNICODE
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ cc += PRIV(OP_lengths)[*cc];
+#ifdef SUPPORT_UNICODE
+ if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2;
+#endif
+ break;
+
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+ cc += GET(cc, 1);
+ break;
+#endif
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ cc += PRIV(OP_lengths)[*cc] + cc[1];
+ break;
+
+ case OP_CALLOUT:
+ cb.pattern_position = GET(cc, 1);
+ cb.next_item_length = GET(cc, 1 + LINK_SIZE);
+ cb.callout_number = cc[1 + 2*LINK_SIZE];
+ cb.callout_string_offset = 0;
+ cb.callout_string_length = 0;
+ cb.callout_string = NULL;
+ rc = callback(&cb, callout_data);
+ if (rc != 0) return rc;
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ case OP_CALLOUT_STR:
+ cb.pattern_position = GET(cc, 1);
+ cb.next_item_length = GET(cc, 1 + LINK_SIZE);
+ cb.callout_number = 0;
+ cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE);
+ cb.callout_string_length =
+ GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2;
+ cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1;
+ rc = callback(&cb, callout_data);
+ if (rc != 0) return rc;
+ cc += GET(cc, 1 + 2*LINK_SIZE);
+ break;
+
+ default:
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+ }
+ }
+}
+
+/* End of pcre2_pattern_info.c */
diff --git a/thirdparty/pcre2/src/pcre2_printint.c b/thirdparty/pcre2/src/pcre2_printint.c
new file mode 100644
index 0000000000..6207497648
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_printint.c
@@ -0,0 +1,832 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains a PCRE private debugging function for printing out the
+internal form of a compiled regular expression, along with some supporting
+local functions. This source file is #included in pcre2test.c at each supported
+code unit width, with PCRE2_SUFFIX set appropriately, just like the functions
+that comprise the library. It can also optionally be included in
+pcre2_compile.c for detailed debugging in error situations. */
+
+
+/* Tables of operator names. The same 8-bit table is used for all code unit
+widths, so it must be defined only once. The list itself is defined in
+pcre2_internal.h, which is #included by pcre2test before this file. */
+
+#ifndef OP_LISTS_DEFINED
+static const char *OP_names[] = { OP_NAME_LIST };
+#define OP_LISTS_DEFINED
+#endif
+
+/* The functions and tables herein must all have mode-dependent names. */
+
+#define OP_lengths PCRE2_SUFFIX(OP_lengths_)
+#define get_ucpname PCRE2_SUFFIX(get_ucpname_)
+#define pcre2_printint PCRE2_SUFFIX(pcre2_printint_)
+#define print_char PCRE2_SUFFIX(print_char_)
+#define print_custring PCRE2_SUFFIX(print_custring_)
+#define print_custring_bylen PCRE2_SUFFIX(print_custring_bylen_)
+#define print_prop PCRE2_SUFFIX(print_prop_)
+
+/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
+the definition is next to the definition of the opcodes in pcre2_internal.h.
+The contents of the table are, however, mode-dependent. */
+
+static const uint8_t OP_lengths[] = { OP_LENGTHS };
+
+
+
+/*************************************************
+* Print one character from a string *
+*************************************************/
+
+/* In UTF mode the character may occupy more than one code unit.
+
+Arguments:
+ f file to write to
+ ptr pointer to first code unit of the character
+ utf TRUE if string is UTF (will be FALSE if UTF is not supported)
+
+Returns: number of additional code units used
+*/
+
+static unsigned int
+print_char(FILE *f, PCRE2_SPTR ptr, BOOL utf)
+{
+uint32_t c = *ptr;
+BOOL one_code_unit = !utf;
+
+/* If UTF is supported and requested, check for a valid single code unit. */
+
+#ifdef SUPPORT_UNICODE
+if (utf)
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ one_code_unit = c < 0x80;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ one_code_unit = (c & 0xfc00) != 0xd800;
+#else
+ one_code_unit = (c & 0xfffff800u) != 0xd800u;
+#endif /* CODE_UNIT_WIDTH */
+ }
+#endif /* SUPPORT_UNICODE */
+
+/* Handle a valid one-code-unit character at any width. */
+
+if (one_code_unit)
+ {
+ if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
+ else if (c < 0x80) fprintf(f, "\\x%02x", c);
+ else fprintf(f, "\\x{%02x}", c);
+ return 0;
+ }
+
+/* Code for invalid UTF code units and multi-unit UTF characters is different
+for each width. If UTF is not supported, control should never get here, but we
+need a return statement to keep the compiler happy. */
+
+#ifndef SUPPORT_UNICODE
+return 0;
+#else
+
+/* Malformed UTF-8 should occur only if the sanity check has been turned off.
+Rather than swallow random bytes, just stop if we hit a bad one. Print it with
+\X instead of \x as an indication. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+if ((c & 0xc0) != 0xc0)
+ {
+ fprintf(f, "\\X{%x}", c); /* Invalid starting byte */
+ return 0;
+ }
+else
+ {
+ int i;
+ int a = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
+ int s = 6*a;
+ c = (c & PRIV(utf8_table3)[a]) << s;
+ for (i = 1; i <= a; i++)
+ {
+ if ((ptr[i] & 0xc0) != 0x80)
+ {
+ fprintf(f, "\\X{%x}", c); /* Invalid secondary byte */
+ return i - 1;
+ }
+ s -= 6;
+ c |= (ptr[i] & 0x3f) << s;
+ }
+ fprintf(f, "\\x{%x}", c);
+ return a;
+}
+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
+
+/* UTF-16: rather than swallow a low surrogate, just stop if we hit a bad one.
+Print it with \X instead of \x as an indication. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 16
+if ((ptr[1] & 0xfc00) != 0xdc00)
+ {
+ fprintf(f, "\\X{%x}", c);
+ return 0;
+ }
+c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000;
+fprintf(f, "\\x{%x}", c);
+return 1;
+#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */
+
+/* For UTF-32 we get here only for a malformed code unit, which should only
+occur if the sanity check has been turned off. Print it with \X instead of \x
+as an indication. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 32
+fprintf(f, "\\X{%x}", c);
+return 0;
+#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */
+#endif /* SUPPORT_UNICODE */
+}
+
+
+
+/*************************************************
+* Print string as a list of code units *
+*************************************************/
+
+/* These take no account of UTF as they always print each individual code unit.
+The string is zero-terminated for print_custring(); the length is given for
+print_custring_bylen().
+
+Arguments:
+ f file to write to
+ ptr point to the string
+ len length for print_custring_bylen()
+
+Returns: nothing
+*/
+
+static void
+print_custring(FILE *f, PCRE2_SPTR ptr)
+{
+while (*ptr != '\0')
+ {
+ uint32_t c = *ptr++;
+ if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
+ }
+}
+
+static void
+print_custring_bylen(FILE *f, PCRE2_SPTR ptr, PCRE2_UCHAR len)
+{
+for (; len > 0; len--)
+ {
+ uint32_t c = *ptr++;
+ if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
+ }
+}
+
+
+
+/*************************************************
+* Find Unicode property name *
+*************************************************/
+
+/* When there is no UTF/UCP support, the table of names does not exist. This
+function should not be called in such configurations, because a pattern that
+tries to use Unicode properties won't compile. Rather than put lots of #ifdefs
+into the main code, however, we just put one into this function. */
+
+static const char *
+get_ucpname(unsigned int ptype, unsigned int pvalue)
+{
+#ifdef SUPPORT_UNICODE
+int i;
+for (i = PRIV(utt_size) - 1; i >= 0; i--)
+ {
+ if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break;
+ }
+return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??";
+#else /* No UTF support */
+(void)ptype;
+(void)pvalue;
+return "??";
+#endif /* SUPPORT_UNICODE */
+}
+
+
+
+/*************************************************
+* Print Unicode property value *
+*************************************************/
+
+/* "Normal" properties can be printed from tables. The PT_CLIST property is a
+pseudo-property that contains a pointer to a list of case-equivalent
+characters.
+
+Arguments:
+ f file to write to
+ code pointer in the compiled code
+ before text to print before
+ after text to print after
+
+Returns: nothing
+*/
+
+static void
+print_prop(FILE *f, PCRE2_SPTR code, const char *before, const char *after)
+{
+if (code[1] != PT_CLIST)
+ {
+ fprintf(f, "%s%s %s%s", before, OP_names[*code], get_ucpname(code[1],
+ code[2]), after);
+ }
+else
+ {
+ const char *not = (*code == OP_PROP)? "" : "not ";
+ const uint32_t *p = PRIV(ucd_caseless_sets) + code[2];
+ fprintf (f, "%s%sclist", before, not);
+ while (*p < NOTACHAR) fprintf(f, " %04x", *p++);
+ fprintf(f, "%s", after);
+ }
+}
+
+
+
+/*************************************************
+* Print compiled pattern *
+*************************************************/
+
+/* The print_lengths flag controls whether offsets and lengths of items are
+printed. Lenths can be turned off from pcre2test so that automatic tests on
+bytecode can be written that do not depend on the value of LINK_SIZE.
+
+Arguments:
+ re a compiled pattern
+ f the file to write to
+ print_lengths show various lengths
+
+Returns: nothing
+*/
+
+static void
+pcre2_printint(pcre2_code *re, FILE *f, BOOL print_lengths)
+{
+PCRE2_SPTR codestart, nametable, code;
+uint32_t nesize = re->name_entry_size;
+BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
+
+nametable = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code));
+code = codestart = nametable + re->name_count * re->name_entry_size;
+
+for(;;)
+ {
+ PCRE2_SPTR ccode;
+ uint32_t c;
+ int i;
+ const char *flag = " ";
+ unsigned int extra = 0;
+
+ if (print_lengths)
+ fprintf(f, "%3d ", (int)(code - codestart));
+ else
+ fprintf(f, " ");
+
+ switch(*code)
+ {
+/* ========================================================================== */
+ /* These cases are never obeyed. This is a fudge that causes a compile-
+ time error if the vectors OP_names or OP_lengths, which are indexed
+ by opcode, are not the correct length. It seems to be the only way to do
+ such a check at compile time, as the sizeof() operator does not work in
+ the C preprocessor. */
+
+ case OP_TABLE_LENGTH:
+ case OP_TABLE_LENGTH +
+ ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
+ (sizeof(OP_lengths) == OP_TABLE_LENGTH)):
+ break;
+/* ========================================================================== */
+
+ case OP_END:
+ fprintf(f, " %s\n", OP_names[*code]);
+ fprintf(f, "------------------------------------------------------------------\n");
+ return;
+
+ case OP_CHAR:
+ fprintf(f, " ");
+ do
+ {
+ code++;
+ code += 1 + print_char(f, code, utf);
+ }
+ while (*code == OP_CHAR);
+ fprintf(f, "\n");
+ continue;
+
+ case OP_CHARI:
+ fprintf(f, " /i ");
+ do
+ {
+ code++;
+ code += 1 + print_char(f, code, utf);
+ }
+ while (*code == OP_CHARI);
+ fprintf(f, "\n");
+ continue;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+ else fprintf(f, " ");
+ fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
+ break;
+
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_ALT:
+ case OP_KET:
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_COND:
+ case OP_SCOND:
+ case OP_REVERSE:
+ if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+ else fprintf(f, " ");
+ fprintf(f, "%s", OP_names[*code]);
+ break;
+
+ case OP_CLOSE:
+ fprintf(f, " %s %d", OP_names[*code], GET2(code, 1));
+ break;
+
+ case OP_CREF:
+ fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
+ break;
+
+ case OP_DNCREF:
+ {
+ PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;
+ fprintf(f, " %s Cond ref <", flag);
+ print_custring(f, entry);
+ fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
+ }
+ break;
+
+ case OP_RREF:
+ c = GET2(code, 1);
+ if (c == RREF_ANY)
+ fprintf(f, " Cond recurse any");
+ else
+ fprintf(f, " Cond recurse %d", c);
+ break;
+
+ case OP_DNRREF:
+ {
+ PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;
+ fprintf(f, " %s Cond recurse <", flag);
+ print_custring(f, entry);
+ fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
+ }
+ break;
+
+ case OP_FALSE:
+ fprintf(f, " Cond false");
+ break;
+
+ case OP_TRUE:
+ fprintf(f, " Cond true");
+ break;
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ flag = "/i";
+ /* Fall through */
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ fprintf(f, " %s ", flag);
+
+ if (*code >= OP_TYPESTAR)
+ {
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
+ {
+ print_prop(f, code + 1, "", " ");
+ extra = 2;
+ }
+ else fprintf(f, "%s", OP_names[code[1]]);
+ }
+ else extra = print_char(f, code+1, utf);
+ fprintf(f, "%s", OP_names[*code]);
+ break;
+
+ case OP_EXACTI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ flag = "/i";
+ /* Fall through */
+ case OP_EXACT:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ fprintf(f, " %s ", flag);
+ extra = print_char(f, code + 1 + IMM2_SIZE, utf);
+ fprintf(f, "{");
+ if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");
+ fprintf(f, "%d}", GET2(code,1));
+ if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");
+ else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");
+ break;
+
+ case OP_TYPEEXACT:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
+ {
+ print_prop(f, code + IMM2_SIZE + 1, " ", " ");
+ extra = 2;
+ }
+ else fprintf(f, " %s", OP_names[code[1 + IMM2_SIZE]]);
+ fprintf(f, "{");
+ if (*code != OP_TYPEEXACT) fprintf(f, "0,");
+ fprintf(f, "%d}", GET2(code,1));
+ if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
+ else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
+ break;
+
+ case OP_NOTI:
+ flag = "/i";
+ /* Fall through */
+ case OP_NOT:
+ fprintf(f, " %s [^", flag);
+ extra = print_char(f, code + 1, utf);
+ fprintf(f, "]");
+ break;
+
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSQUERYI:
+ flag = "/i";
+ /* Fall through */
+
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSQUERY:
+ fprintf(f, " %s [^", flag);
+ extra = print_char(f, code + 1, utf);
+ fprintf(f, "]%s", OP_names[*code]);
+ break;
+
+ case OP_NOTEXACTI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPOSUPTOI:
+ flag = "/i";
+ /* Fall through */
+
+ case OP_NOTEXACT:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTPOSUPTO:
+ fprintf(f, " %s [^", flag);
+ extra = print_char(f, code + 1 + IMM2_SIZE, utf);
+ fprintf(f, "]{");
+ if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");
+ fprintf(f, "%d}", GET2(code,1));
+ if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");
+ else
+ if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");
+ break;
+
+ case OP_RECURSE:
+ if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+ else fprintf(f, " ");
+ fprintf(f, "%s", OP_names[*code]);
+ break;
+
+ case OP_REFI:
+ flag = "/i";
+ /* Fall through */
+ case OP_REF:
+ fprintf(f, " %s \\%d", flag, GET2(code,1));
+ ccode = code + OP_lengths[*code];
+ goto CLASS_REF_REPEAT;
+
+ case OP_DNREFI:
+ flag = "/i";
+ /* Fall through */
+ case OP_DNREF:
+ {
+ PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;
+ fprintf(f, " %s \\k<", flag);
+ print_custring(f, entry);
+ fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
+ }
+ ccode = code + OP_lengths[*code];
+ goto CLASS_REF_REPEAT;
+
+ case OP_CALLOUT:
+ fprintf(f, " %s %d %d %d", OP_names[*code], code[1 + 2*LINK_SIZE],
+ GET(code, 1), GET(code, 1 + LINK_SIZE));
+ break;
+
+ case OP_CALLOUT_STR:
+ c = code[1 + 4*LINK_SIZE];
+ fprintf(f, " %s %c", OP_names[*code], c);
+ extra = GET(code, 1 + 2*LINK_SIZE);
+ print_custring_bylen(f, code + 2 + 4*LINK_SIZE, extra - 3 - 4*LINK_SIZE);
+ for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
+ if (c == PRIV(callout_start_delims)[i])
+ {
+ c = PRIV(callout_end_delims)[i];
+ break;
+ }
+ fprintf(f, "%c %d %d %d", c, GET(code, 1 + 3*LINK_SIZE), GET(code, 1),
+ GET(code, 1 + LINK_SIZE));
+ break;
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ print_prop(f, code, " ", "");
+ break;
+
+ /* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm
+ in having this code always here, and it makes it less messy without all
+ those #ifdefs. */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_XCLASS:
+ {
+ unsigned int min, max;
+ BOOL printmap;
+ BOOL invertmap = FALSE;
+ uint8_t *map;
+ uint8_t inverted_map[32];
+
+ fprintf(f, " [");
+
+ if (*code == OP_XCLASS)
+ {
+ extra = GET(code, 1);
+ ccode = code + LINK_SIZE + 1;
+ printmap = (*ccode & XCL_MAP) != 0;
+ if ((*ccode & XCL_NOT) != 0)
+ {
+ invertmap = (*ccode & XCL_HASPROP) == 0;
+ fprintf(f, "^");
+ }
+ ccode++;
+ }
+ else
+ {
+ printmap = TRUE;
+ ccode = code + 1;
+ }
+
+ /* Print a bit map */
+
+ if (printmap)
+ {
+ map = (uint8_t *)ccode;
+ if (invertmap)
+ {
+ for (i = 0; i < 32; i++) inverted_map[i] = ~map[i];
+ map = inverted_map;
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ if ((map[i/8] & (1 << (i&7))) != 0)
+ {
+ int j;
+ for (j = i+1; j < 256; j++)
+ if ((map[j/8] & (1 << (j&7))) == 0) break;
+ if (i == '-' || i == ']') fprintf(f, "\\");
+ if (PRINTABLE(i)) fprintf(f, "%c", i);
+ else fprintf(f, "\\x%02x", i);
+ if (--j > i)
+ {
+ if (j != i + 1) fprintf(f, "-");
+ if (j == '-' || j == ']') fprintf(f, "\\");
+ if (PRINTABLE(j)) fprintf(f, "%c", j);
+ else fprintf(f, "\\x%02x", j);
+ }
+ i = j;
+ }
+ }
+ ccode += 32 / sizeof(PCRE2_UCHAR);
+ }
+
+ /* For an XCLASS there is always some additional data */
+
+ if (*code == OP_XCLASS)
+ {
+ PCRE2_UCHAR ch;
+ while ((ch = *ccode++) != XCL_END)
+ {
+ BOOL not = FALSE;
+ const char *notch = "";
+
+ switch(ch)
+ {
+ case XCL_NOTPROP:
+ not = TRUE;
+ notch = "^";
+ /* Fall through */
+
+ case XCL_PROP:
+ {
+ unsigned int ptype = *ccode++;
+ unsigned int pvalue = *ccode++;
+
+ switch(ptype)
+ {
+ case PT_PXGRAPH:
+ fprintf(f, "[:%sgraph:]", notch);
+ break;
+
+ case PT_PXPRINT:
+ fprintf(f, "[:%sprint:]", notch);
+ break;
+
+ case PT_PXPUNCT:
+ fprintf(f, "[:%spunct:]", notch);
+ break;
+
+ default:
+ fprintf(f, "\\%c{%s}", (not? 'P':'p'),
+ get_ucpname(ptype, pvalue));
+ break;
+ }
+ }
+ break;
+
+ default:
+ ccode += 1 + print_char(f, ccode, utf);
+ if (ch == XCL_RANGE)
+ {
+ fprintf(f, "-");
+ ccode += 1 + print_char(f, ccode, utf);
+ }
+ break;
+ }
+ }
+ }
+
+ /* Indicate a non-UTF class which was created by negation */
+
+ fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
+
+ /* Handle repeats after a class or a back reference */
+
+ CLASS_REF_REPEAT:
+ switch(*ccode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
+ fprintf(f, "%s", OP_names[*ccode]);
+ extra += OP_lengths[*ccode];
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ min = GET2(ccode,1);
+ max = GET2(ccode,1 + IMM2_SIZE);
+ if (max == 0) fprintf(f, "{%u,}", min);
+ else fprintf(f, "{%u,%u}", min, max);
+ if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
+ else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+");
+ extra += OP_lengths[*ccode];
+ break;
+
+ /* Do nothing if it's not a repeat; this code stops picky compilers
+ warning about the lack of a default code path. */
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ fprintf(f, " %s ", OP_names[*code]);
+ print_custring_bylen(f, code + 2, code[1]);
+ extra += code[1];
+ break;
+
+ case OP_THEN:
+ fprintf(f, " %s", OP_names[*code]);
+ break;
+
+ case OP_CIRCM:
+ case OP_DOLLM:
+ flag = "/m";
+ /* Fall through */
+
+ /* Anything else is just an item with no data, but possibly a flag. */
+
+ default:
+ fprintf(f, " %s %s", flag, OP_names[*code]);
+ break;
+ }
+
+ code += OP_lengths[*code] + extra;
+ fprintf(f, "\n");
+ }
+}
+
+/* End of pcre2_printint.c */
diff --git a/thirdparty/pcre2/src/pcre2_serialize.c b/thirdparty/pcre2/src/pcre2_serialize.c
new file mode 100644
index 0000000000..0af26d8fc3
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_serialize.c
@@ -0,0 +1,265 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This module contains functions for serializing and deserializing
+a sequence of compiled codes. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "pcre2_internal.h"
+
+/* Magic number to provide a small check against being handed junk. */
+
+#define SERIALIZED_DATA_MAGIC 0x50523253u
+
+/* Deserialization is limited to the current PCRE version and
+character width. */
+
+#define SERIALIZED_DATA_VERSION \
+ ((PCRE2_MAJOR) | ((PCRE2_MINOR) << 16))
+
+#define SERIALIZED_DATA_CONFIG \
+ (sizeof(PCRE2_UCHAR) | ((sizeof(void*)) << 8) | ((sizeof(PCRE2_SIZE)) << 16))
+
+
+
+/*************************************************
+* Serialize compiled patterns *
+*************************************************/
+
+PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION
+pcre2_serialize_encode(const pcre2_code **codes, int32_t number_of_codes,
+ uint8_t **serialized_bytes, PCRE2_SIZE *serialized_size,
+ pcre2_general_context *gcontext)
+{
+uint8_t *bytes;
+uint8_t *dst_bytes;
+int32_t i;
+PCRE2_SIZE total_size;
+const pcre2_real_code *re;
+const uint8_t *tables;
+pcre2_serialized_data *data;
+
+const pcre2_memctl *memctl = (gcontext != NULL) ?
+ &gcontext->memctl : &PRIV(default_compile_context).memctl;
+
+if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL)
+ return PCRE2_ERROR_NULL;
+
+if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;
+
+/* Compute total size. */
+total_size = sizeof(pcre2_serialized_data) + tables_length;
+tables = NULL;
+
+for (i = 0; i < number_of_codes; i++)
+ {
+ if (codes[i] == NULL) return PCRE2_ERROR_NULL;
+ re = (const pcre2_real_code *)(codes[i]);
+ if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+ if (tables == NULL)
+ tables = re->tables;
+ else if (tables != re->tables)
+ return PCRE2_ERROR_MIXEDTABLES;
+ total_size += re->blocksize;
+ }
+
+/* Initialize the byte stream. */
+bytes = memctl->malloc(total_size + sizeof(pcre2_memctl), memctl->memory_data);
+if (bytes == NULL) return PCRE2_ERROR_NOMEMORY;
+
+/* The controller is stored as a hidden parameter. */
+memcpy(bytes, memctl, sizeof(pcre2_memctl));
+bytes += sizeof(pcre2_memctl);
+
+data = (pcre2_serialized_data *)bytes;
+data->magic = SERIALIZED_DATA_MAGIC;
+data->version = SERIALIZED_DATA_VERSION;
+data->config = SERIALIZED_DATA_CONFIG;
+data->number_of_codes = number_of_codes;
+
+/* Copy all compiled code data. */
+dst_bytes = bytes + sizeof(pcre2_serialized_data);
+memcpy(dst_bytes, tables, tables_length);
+dst_bytes += tables_length;
+
+for (i = 0; i < number_of_codes; i++)
+ {
+ re = (const pcre2_real_code *)(codes[i]);
+ memcpy(dst_bytes, (char *)re, re->blocksize);
+ dst_bytes += re->blocksize;
+ }
+
+*serialized_bytes = bytes;
+*serialized_size = total_size;
+return number_of_codes;
+}
+
+
+/*************************************************
+* Deserialize compiled patterns *
+*************************************************/
+
+PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION
+pcre2_serialize_decode(pcre2_code **codes, int32_t number_of_codes,
+ const uint8_t *bytes, pcre2_general_context *gcontext)
+{
+const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;
+const pcre2_memctl *memctl = (gcontext != NULL) ?
+ &gcontext->memctl : &PRIV(default_compile_context).memctl;
+
+const uint8_t *src_bytes;
+pcre2_real_code *dst_re;
+uint8_t *tables;
+int32_t i, j;
+
+/* Sanity checks. */
+
+if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL;
+if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;
+if (data->number_of_codes <= 0) return PCRE2_ERROR_BADSERIALIZEDDATA;
+if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;
+if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;
+if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;
+
+if (number_of_codes > data->number_of_codes)
+ number_of_codes = data->number_of_codes;
+
+src_bytes = bytes + sizeof(pcre2_serialized_data);
+
+/* Decode tables. The reference count for the tables is stored immediately
+following them. */
+
+tables = memctl->malloc(tables_length + sizeof(PCRE2_SIZE), memctl->memory_data);
+if (tables == NULL) return PCRE2_ERROR_NOMEMORY;
+
+memcpy(tables, src_bytes, tables_length);
+*(PCRE2_SIZE *)(tables + tables_length) = number_of_codes;
+src_bytes += tables_length;
+
+/* Decode the byte stream. We must not try to read the size from the compiled
+code block in the stream, because it might be unaligned, which causes errors on
+hardware such as Sparc-64 that doesn't like unaligned memory accesses. The type
+of the blocksize field is given its own name to ensure that it is the same here
+as in the block. */
+
+for (i = 0; i < number_of_codes; i++)
+ {
+ CODE_BLOCKSIZE_TYPE blocksize;
+ memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize),
+ sizeof(CODE_BLOCKSIZE_TYPE));
+ if (blocksize <= sizeof(pcre2_real_code))
+ return PCRE2_ERROR_BADSERIALIZEDDATA;
+
+ /* The allocator provided by gcontext replaces the original one. */
+
+ dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize,
+ (pcre2_memctl *)gcontext);
+ if (dst_re == NULL)
+ {
+ memctl->free(tables, memctl->memory_data);
+ for (j = 0; j < i; j++)
+ {
+ memctl->free(codes[j], memctl->memory_data);
+ codes[j] = NULL;
+ }
+ return PCRE2_ERROR_NOMEMORY;
+ }
+
+ /* The new allocator must be preserved. */
+
+ memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl),
+ src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl));
+ if (dst_re->magic_number != MAGIC_NUMBER ||
+ dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 ||
+ dst_re->name_count > MAX_NAME_COUNT)
+ return PCRE2_ERROR_BADSERIALIZEDDATA;
+
+ /* At the moment only one table is supported. */
+
+ dst_re->tables = tables;
+ dst_re->executable_jit = NULL;
+ dst_re->flags |= PCRE2_DEREF_TABLES;
+
+ codes[i] = dst_re;
+ src_bytes += blocksize;
+ }
+
+return number_of_codes;
+}
+
+
+/*************************************************
+* Get the number of serialized patterns *
+*************************************************/
+
+PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION
+pcre2_serialize_get_number_of_codes(const uint8_t *bytes)
+{
+const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;
+
+if (data == NULL) return PCRE2_ERROR_NULL;
+if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;
+if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;
+if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;
+
+return data->number_of_codes;
+}
+
+
+/*************************************************
+* Free the allocated stream *
+*************************************************/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_serialize_free(uint8_t *bytes)
+{
+if (bytes != NULL)
+ {
+ pcre2_memctl *memctl = (pcre2_memctl *)(bytes - sizeof(pcre2_memctl));
+ memctl->free(memctl, memctl->memory_data);
+ }
+}
+
+/* End of pcre2_serialize.c */
diff --git a/thirdparty/pcre2/src/pcre2_string_utils.c b/thirdparty/pcre2/src/pcre2_string_utils.c
new file mode 100644
index 0000000000..2a1f282629
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_string_utils.c
@@ -0,0 +1,201 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This module contains internal functions for comparing and finding the length
+of strings. These are used instead of strcmp() etc because the standard
+functions work only on 8-bit data. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+/*************************************************
+* Compare two zero-terminated PCRE2 strings *
+*************************************************/
+
+/*
+Arguments:
+ str1 first string
+ str2 second string
+
+Returns: 0, 1, or -1
+*/
+
+int
+PRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2)
+{
+PCRE2_UCHAR c1, c2;
+while (*str1 != '\0' || *str2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2) return ((c1 > c2) << 1) - 1;
+ }
+return 0;
+}
+
+
+/*************************************************
+* Compare zero-terminated PCRE2 & 8-bit strings *
+*************************************************/
+
+/* As the 8-bit string is almost always a literal, its type is specified as
+const char *.
+
+Arguments:
+ str1 first string
+ str2 second string
+
+Returns: 0, 1, or -1
+*/
+
+int
+PRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2)
+{
+PCRE2_UCHAR c1, c2;
+while (*str1 != '\0' || *str2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2) return ((c1 > c2) << 1) - 1;
+ }
+return 0;
+}
+
+
+/*************************************************
+* Compare two PCRE2 strings, given a length *
+*************************************************/
+
+/*
+Arguments:
+ str1 first string
+ str2 second string
+ len the length
+
+Returns: 0, 1, or -1
+*/
+
+int
+PRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len)
+{
+PCRE2_UCHAR c1, c2;
+for (; len > 0; len--)
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2) return ((c1 > c2) << 1) - 1;
+ }
+return 0;
+}
+
+
+/*************************************************
+* Compare PCRE2 string to 8-bit string by length *
+*************************************************/
+
+/* As the 8-bit string is almost always a literal, its type is specified as
+const char *.
+
+Arguments:
+ str1 first string
+ str2 second string
+ len the length
+
+Returns: 0, 1, or -1
+*/
+
+int
+PRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len)
+{
+PCRE2_UCHAR c1, c2;
+for (; len > 0; len--)
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2) return ((c1 > c2) << 1) - 1;
+ }
+return 0;
+}
+
+
+/*************************************************
+* Find the length of a PCRE2 string *
+*************************************************/
+
+/*
+Argument: the string
+Returns: the length
+*/
+
+PCRE2_SIZE
+PRIV(strlen)(PCRE2_SPTR str)
+{
+PCRE2_SIZE c = 0;
+while (*str++ != 0) c++;
+return c;
+}
+
+
+/*************************************************
+* Copy 8-bit 0-terminated string to PCRE2 string *
+*************************************************/
+
+/* Arguments:
+ str1 buffer to receive the string
+ str2 8-bit string to be copied
+
+Returns: the number of code units used (excluding trailing zero)
+*/
+
+PCRE2_SIZE
+PRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2)
+{
+PCRE2_UCHAR *t = str1;
+while (*str2 != 0) *t++ = *str2++;
+*t = 0;
+return t - str1;
+}
+
+/* End of pcre2_string_utils.c */
diff --git a/thirdparty/pcre2/src/pcre2_study.c b/thirdparty/pcre2/src/pcre2_study.c
new file mode 100644
index 0000000000..5a4d520c09
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_study.c
@@ -0,0 +1,1625 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This module contains functions for scanning a compiled pattern and
+collecting data (e.g. minimum matching length). */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "pcre2_internal.h"
+
+
+/* The maximum remembered capturing brackets minimum. */
+
+#define MAX_CACHE_BACKREF 128
+
+/* Set a bit in the starting code unit bit map. */
+
+#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1 << ((c)&7))
+
+/* Returns from set_start_bits() */
+
+enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
+
+
+/*************************************************
+* Find the minimum subject length for a group *
+*************************************************/
+
+/* Scan a parenthesized group and compute the minimum length of subject that
+is needed to match it. This is a lower bound; it does not mean there is a
+string of that length that matches. In UTF mode, the result is in characters
+rather than code units. The field in a compiled pattern for storing the minimum
+length is 16-bits long (on the grounds that anything longer than that is
+pathological), so we give up when we reach that amount. This also means that
+integer overflow for really crazy patterns cannot happen.
+
+Backreference minimum lengths are cached to speed up multiple references. This
+function is called only when the highest back reference in the pattern is less
+than or equal to MAX_CACHE_BACKREF, which is one less than the size of the
+caching vector. The zeroth element contains the number of the highest set
+value.
+
+Arguments:
+ re compiled pattern block
+ code pointer to start of group (the bracket)
+ startcode pointer to start of the whole pattern's code
+ utf UTF flag
+ recurses chain of recurse_check to catch mutual recursion
+ countptr pointer to call count (to catch over complexity)
+ backref_cache vector for caching back references.
+
+Returns: the minimum length
+ -1 \C in UTF-8 mode
+ or (*ACCEPT)
+ or pattern too complicated
+ or back reference to duplicate name/number
+ -2 internal error (missing capturing bracket)
+ -3 internal error (opcode not listed)
+*/
+
+static int
+find_minlength(const pcre2_real_code *re, PCRE2_SPTR code,
+ PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr,
+ int *backref_cache)
+{
+int length = -1;
+int prev_cap_recno = -1;
+int prev_cap_d = 0;
+int prev_recurse_recno = -1;
+int prev_recurse_d = 0;
+uint32_t once_fudge = 0;
+BOOL had_recurse = FALSE;
+BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0;
+recurse_check this_recurse;
+int branchlength = 0;
+PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE;
+
+/* If this is a "could be empty" group, its minimum length is 0. */
+
+if (*code >= OP_SBRA && *code <= OP_SCOND) return 0;
+
+/* Skip over capturing bracket number */
+
+if (*code == OP_CBRA || *code == OP_CBRAPOS) cc += IMM2_SIZE;
+
+/* A large and/or complex regex can take too long to process. */
+
+if ((*countptr)++ > 1000) return -1;
+
+/* Scan along the opcodes for this branch. If we get to the end of the branch,
+check the length against that of the other branches. If the accumulated length
+passes 16-bits, stop. */
+
+for (;;)
+ {
+ int d, min, recno;
+ PCRE2_UCHAR *cs, *ce;
+ PCRE2_UCHAR op = *cc;
+
+ if (branchlength >= UINT16_MAX) return UINT16_MAX;
+
+ switch (op)
+ {
+ case OP_COND:
+ case OP_SCOND:
+
+ /* If there is only one branch in a condition, the implied branch has zero
+ length, so we don't add anything. This covers the DEFINE "condition"
+ automatically. If there are two branches we can treat it the same as any
+ other non-capturing subpattern. */
+
+ cs = cc + GET(cc, 1);
+ if (*cs != OP_ALT)
+ {
+ cc = cs + 1 + LINK_SIZE;
+ break;
+ }
+ goto PROCESS_NON_CAPTURE;
+
+ /* There's a special case of OP_ONCE, when it is wrapped round an
+ OP_RECURSE. We'd like to process the latter at this level so that
+ remembering the value works for repeated cases. So we do nothing, but
+ set a fudge value to skip over the OP_KET after the recurse. */
+
+ case OP_ONCE:
+ if (cc[1+LINK_SIZE] == OP_RECURSE && cc[2*(1+LINK_SIZE)] == OP_KET)
+ {
+ once_fudge = 1 + LINK_SIZE;
+ cc += 1 + LINK_SIZE;
+ break;
+ }
+ /* Fall through */
+
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_SBRA:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ PROCESS_NON_CAPTURE:
+ d = find_minlength(re, cc, startcode, utf, recurses, countptr,
+ backref_cache);
+ if (d < 0) return d;
+ branchlength += d;
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* To save time for repeated capturing subpatterns, we remember the
+ length of the previous one. Unfortunately we can't do the same for
+ the unnumbered ones above. Nor can we do this if (?| is present in the
+ pattern because captures with the same number are not then identical. */
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ recno = (int)GET2(cc, 1+LINK_SIZE);
+ if (dupcapused || recno != prev_cap_recno)
+ {
+ prev_cap_recno = recno;
+ prev_cap_d = find_minlength(re, cc, startcode, utf, recurses, countptr,
+ backref_cache);
+ if (prev_cap_d < 0) return prev_cap_d;
+ }
+ branchlength += prev_cap_d;
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* ACCEPT makes things far too complicated; we have to give up. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ return -1;
+
+ /* Reached end of a branch; if it's a ket it is the end of a nested
+ call. If it's ALT it is an alternation in a nested call. If it is END it's
+ the end of the outer call. All can be handled by the same code. If an
+ ACCEPT was previously encountered, use the length that was in force at that
+ time, and pass back the shortest ACCEPT length. */
+
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_END:
+ if (length < 0 || (!had_recurse && branchlength < length))
+ length = branchlength;
+ if (op != OP_ALT) return length;
+ cc += 1 + LINK_SIZE;
+ branchlength = 0;
+ had_recurse = FALSE;
+ break;
+
+ /* Skip over assertive subpatterns */
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ /* Fall through */
+
+ /* Skip over things that don't match chars */
+
+ case OP_REVERSE:
+ case OP_CREF:
+ case OP_DNCREF:
+ case OP_RREF:
+ case OP_DNRREF:
+ case OP_FALSE:
+ case OP_TRUE:
+ case OP_CALLOUT:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ case OP_CALLOUT_STR:
+ cc += GET(cc, 1 + 2*LINK_SIZE);
+ break;
+
+ /* Skip over a subpattern that has a {0} or {0,x} quantifier */
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ case OP_SKIPZERO:
+ cc += PRIV(OP_lengths)[*cc];
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Handle literal characters and + repetitions */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ branchlength++;
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ branchlength++;
+ cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;
+ break;
+
+ /* Handle exact repetitions. The count is already in characters, but we
+ may need to skip over a multibyte character in UTF mode. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UNICODE
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEEXACT:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+ break;
+
+ /* Handle single-char non-literal matchers */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ cc += 2;
+ /* Fall through */
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_EXTUNI:
+ case OP_HSPACE:
+ case OP_NOT_HSPACE:
+ case OP_VSPACE:
+ case OP_NOT_VSPACE:
+ branchlength++;
+ cc++;
+ break;
+
+ /* "Any newline" might match two characters, but it also might match just
+ one. */
+
+ case OP_ANYNL:
+ branchlength += 1;
+ cc++;
+ break;
+
+ /* The single-byte matcher means we can't proceed in UTF mode. (In
+ non-UTF mode \C will actually be turned into OP_ALLANY, so won't ever
+ appear, but leave the code, just in case.) */
+
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UNICODE
+ if (utf) return -1;
+#endif
+ branchlength++;
+ cc++;
+ break;
+
+ /* For repeated character types, we have to test for \p and \P, which have
+ an extra two bytes of parameters. */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSQUERY:
+ if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ if (cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ /* Check a class for variable quantification */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ /* The original code caused an unsigned overflow in 64 bit systems,
+ so now we use a conditional statement. */
+ if (op == OP_XCLASS)
+ cc += GET(cc, 1);
+ else
+ cc += PRIV(OP_lengths)[OP_CLASS];
+#else
+ cc += PRIV(OP_lengths)[OP_CLASS];
+#endif
+
+ switch (*cc)
+ {
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
+ branchlength++;
+ /* Fall through */
+
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
+ cc++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ branchlength += GET2(cc,1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ branchlength++;
+ break;
+ }
+ break;
+
+ /* Backreferences and subroutine calls (OP_RECURSE) are treated in the same
+ way: we find the minimum length for the subpattern. A recursion
+ (backreference or subroutine) causes an a flag to be set that causes the
+ length of this branch to be ignored. The logic is that a recursion can only
+ make sense if there is another alternative that stops the recursing. That
+ will provide the minimum length (when no recursion happens).
+
+ If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket
+ matches an empty string (by default it causes a matching failure), so in
+ that case we must set the minimum length to zero. */
+
+ /* Duplicate named pattern back reference. We cannot reliably find a length
+ for this if duplicate numbers are present in the pattern. */
+
+ case OP_DNREF:
+ case OP_DNREFI:
+ if (dupcapused) return -1;
+ if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
+ {
+ int count = GET2(cc, 1+IMM2_SIZE);
+ PCRE2_UCHAR *slot =
+ (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
+ GET2(cc, 1) * re->name_entry_size;
+
+ d = INT_MAX;
+
+ /* Scan all groups with the same name; find the shortest. */
+
+ while (count-- > 0)
+ {
+ int dd, i;
+ recno = GET2(slot, 0);
+
+ if (recno <= backref_cache[0] && backref_cache[recno] >= 0)
+ dd = backref_cache[recno];
+ else
+ {
+ ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
+ if (cs == NULL) return -2;
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if (cc > cs && cc < ce) /* Simple recursion */
+ {
+ dd = 0;
+ had_recurse = TRUE;
+ }
+ else
+ {
+ recurse_check *r = recurses;
+ for (r = recurses; r != NULL; r = r->prev)
+ if (r->group == cs) break;
+ if (r != NULL) /* Mutual recursion */
+ {
+ dd = 0;
+ had_recurse = TRUE;
+ }
+ else
+ {
+ this_recurse.prev = recurses;
+ this_recurse.group = cs;
+ dd = find_minlength(re, cs, startcode, utf, &this_recurse,
+ countptr, backref_cache);
+ if (dd < 0) return dd;
+ }
+ }
+
+ backref_cache[recno] = dd;
+ for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;
+ backref_cache[0] = recno;
+ }
+
+ if (dd < d) d = dd;
+ if (d <= 0) break; /* No point looking at any more */
+ slot += re->name_entry_size;
+ }
+ }
+ else d = 0;
+ cc += 1 + 2*IMM2_SIZE;
+ goto REPEAT_BACK_REFERENCE;
+
+ /* Single back reference. We cannot find a length for this if duplicate
+ numbers are present in the pattern. */
+
+ case OP_REF:
+ case OP_REFI:
+ if (dupcapused) return -1;
+ recno = GET2(cc, 1);
+ if (recno <= backref_cache[0] && backref_cache[recno] >= 0)
+ d = backref_cache[recno];
+ else
+ {
+ int i;
+ if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
+ {
+ ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
+ if (cs == NULL) return -2;
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if (cc > cs && cc < ce) /* Simple recursion */
+ {
+ d = 0;
+ had_recurse = TRUE;
+ }
+ else
+ {
+ recurse_check *r = recurses;
+ for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
+ if (r != NULL) /* Mutual recursion */
+ {
+ d = 0;
+ had_recurse = TRUE;
+ }
+ else
+ {
+ this_recurse.prev = recurses;
+ this_recurse.group = cs;
+ d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr,
+ backref_cache);
+ if (d < 0) return d;
+ }
+ }
+ }
+ else d = 0;
+
+ backref_cache[recno] = d;
+ for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;
+ backref_cache[0] = recno;
+ }
+
+ cc += 1 + IMM2_SIZE;
+
+ /* Handle repeated back references */
+
+ REPEAT_BACK_REFERENCE:
+ switch (*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
+ min = 0;
+ cc++;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
+ min = 1;
+ cc++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ min = GET2(cc, 1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ min = 1;
+ break;
+ }
+
+ /* Take care not to overflow: (1) min and d are ints, so check that their
+ product is not greater than INT_MAX. (2) branchlength is limited to
+ UINT16_MAX (checked at the top of the loop). */
+
+ if ((d > 0 && (INT_MAX/d) < min) || UINT16_MAX - branchlength < min*d)
+ branchlength = UINT16_MAX;
+ else branchlength += min * d;
+ break;
+
+ /* Recursion always refers to the first occurrence of a subpattern with a
+ given number. Therefore, we can always make use of caching, even when the
+ pattern contains multiple subpatterns with the same number. */
+
+ case OP_RECURSE:
+ cs = ce = (PCRE2_UCHAR *)startcode + GET(cc, 1);
+ recno = GET2(cs, 1+LINK_SIZE);
+ if (recno == prev_recurse_recno)
+ {
+ branchlength += prev_recurse_d;
+ }
+ else
+ {
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if (cc > cs && cc < ce) /* Simple recursion */
+ had_recurse = TRUE;
+ else
+ {
+ recurse_check *r = recurses;
+ for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
+ if (r != NULL) /* Mutual recursion */
+ had_recurse = TRUE;
+ else
+ {
+ this_recurse.prev = recurses;
+ this_recurse.group = cs;
+ prev_recurse_d = find_minlength(re, cs, startcode, utf, &this_recurse,
+ countptr, backref_cache);
+ if (prev_recurse_d < 0) return prev_recurse_d;
+ prev_recurse_recno = recno;
+ branchlength += prev_recurse_d;
+ }
+ }
+ }
+ cc += 1 + LINK_SIZE + once_fudge;
+ once_fudge = 0;
+ break;
+
+ /* Anything else does not or need not match a character. We can get the
+ item's length from the table, but for those that can match zero occurrences
+ of a character, we must take special action for UTF-8 characters. As it
+ happens, the "NOT" versions of these opcodes are used at present only for
+ ASCII characters, so they could be omitted from this list. However, in
+ future that may change, so we include them here so as not to leave a
+ gotcha for a future maintainer. */
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+
+ case OP_STAR:
+ case OP_STARI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+
+ cc += PRIV(OP_lengths)[op];
+#ifdef SUPPORT_UNICODE
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ /* Skip these, but we need to add in the name length. */
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ cc += PRIV(OP_lengths)[op] + cc[1];
+ break;
+
+ /* The remaining opcodes are just skipped over. */
+
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_FAIL:
+ case OP_PRUNE:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_THEN:
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ /* This should not occur: we list all opcodes explicitly so that when
+ new ones get added they are properly considered. */
+
+ default:
+ return -3;
+ }
+ }
+/* Control never gets here */
+}
+
+
+
+/*************************************************
+* Set a bit and maybe its alternate case *
+*************************************************/
+
+/* Given a character, set its first code unit's bit in the table, and also the
+corresponding bit for the other version of a letter if we are caseless.
+
+Arguments:
+ re points to the regex block
+ p points to the first code unit of the character
+ caseless TRUE if caseless
+ utf TRUE for UTF mode
+
+Returns: pointer after the character
+*/
+
+static PCRE2_SPTR
+set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf)
+{
+uint32_t c = *p++; /* First code unit */
+(void)utf; /* Stop compiler warning when UTF not supported */
+
+/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for
+0xff. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+if (c > 0xff) SET_BIT(0xff); else
+#endif
+
+SET_BIT(c);
+
+/* In UTF-8 or UTF-16 mode, pick up the remaining code units in order to find
+the end of the character, even when caseless. */
+
+#ifdef SUPPORT_UNICODE
+if (utf)
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (c >= 0xc0) GETUTF8INC(c, p);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, p);
+#endif
+ }
+#endif /* SUPPORT_UNICODE */
+
+/* If caseless, handle the other case of the character. */
+
+if (caseless)
+ {
+ if (utf)
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ PCRE2_UCHAR buff[6];
+ c = UCD_OTHERCASE(c);
+ (void)PRIV(ord2utf)(c, buff);
+ SET_BIT(buff[0]);
+#else /* 16-bit or 32-bit mode */
+ c = UCD_OTHERCASE(c);
+ if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
+#endif
+ }
+
+ /* Not UTF */
+
+ else if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);
+ }
+
+return p;
+}
+
+
+
+/*************************************************
+* Set bits for a positive character type *
+*************************************************/
+
+/* This function sets starting bits for a character type. In UTF-8 mode, we can
+only do a direct setting for bytes less than 128, as otherwise there can be
+confusion with bytes in the middle of UTF-8 characters. In a "traditional"
+environment, the tables will only recognize ASCII characters anyway, but in at
+least one Windows environment, some higher bytes bits were set in the tables.
+So we deal with that case by considering the UTF-8 encoding.
+
+Arguments:
+ re the regex block
+ cbit type the type of character wanted
+ table_limit 32 for non-UTF-8; 16 for UTF-8
+
+Returns: nothing
+*/
+
+static void
+set_type_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)
+{
+uint32_t c;
+for (c = 0; c < table_limit; c++)
+ re->start_bitmap[c] |= re->tables[c+cbits_offset+cbit_type];
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+if (table_limit == 32) return;
+for (c = 128; c < 256; c++)
+ {
+ if ((re->tables[cbits_offset + c/8] & (1 << (c&7))) != 0)
+ {
+ PCRE2_UCHAR buff[6];
+ (void)PRIV(ord2utf)(c, buff);
+ SET_BIT(buff[0]);
+ }
+ }
+#endif /* UTF-8 */
+}
+
+
+/*************************************************
+* Set bits for a negative character type *
+*************************************************/
+
+/* This function sets starting bits for a negative character type such as \D.
+In UTF-8 mode, we can only do a direct setting for bytes less than 128, as
+otherwise there can be confusion with bytes in the middle of UTF-8 characters.
+Unlike in the positive case, where we can set appropriate starting bits for
+specific high-valued UTF-8 characters, in this case we have to set the bits for
+all high-valued characters. The lowest is 0xc2, but we overkill by starting at
+0xc0 (192) for simplicity.
+
+Arguments:
+ re the regex block
+ cbit type the type of character wanted
+ table_limit 32 for non-UTF-8; 16 for UTF-8
+
+Returns: nothing
+*/
+
+static void
+set_nottype_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)
+{
+uint32_t c;
+for (c = 0; c < table_limit; c++)
+ re->start_bitmap[c] |= ~(re->tables[c+cbits_offset+cbit_type]);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff;
+#endif
+}
+
+
+
+/*************************************************
+* Create bitmap of starting bytes *
+*************************************************/
+
+/* This function scans a compiled unanchored expression recursively and
+attempts to build a bitmap of the set of possible starting code units whose
+values are less than 256. In 16-bit and 32-bit mode, values above 255 all cause
+the 255 bit to be set. When calling set[_not]_type_bits() in UTF-8 (sic) mode
+we pass a value of 16 rather than 32 as the final argument. (See comments in
+those functions for the reason.)
+
+The SSB_CONTINUE return is useful for parenthesized groups in patterns such as
+(a*)b where the group provides some optional starting code units but scanning
+must continue at the outer level to find at least one mandatory code unit. At
+the outermost level, this function fails unless the result is SSB_DONE.
+
+Arguments:
+ re points to the compiled regex block
+ code points to an expression
+ utf TRUE if in UTF mode
+
+Returns: SSB_FAIL => Failed to find any starting code units
+ SSB_DONE => Found mandatory starting code units
+ SSB_CONTINUE => Found optional starting code units
+ SSB_UNKNOWN => Hit an unrecognized opcode
+*/
+
+static int
+set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf)
+{
+uint32_t c;
+int yield = SSB_DONE;
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+int table_limit = utf? 16:32;
+#else
+int table_limit = 32;
+#endif
+
+do
+ {
+ BOOL try_next = TRUE;
+ PCRE2_SPTR tcode = code + 1 + LINK_SIZE;
+
+ if (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;
+
+ while (try_next) /* Loop for items in this branch */
+ {
+ int rc;
+ uint8_t *classmap = NULL;
+
+ switch(*tcode)
+ {
+ /* If we reach something we don't understand, it means a new opcode has
+ been created that hasn't been added to this function. Hopefully this
+ problem will be discovered during testing. */
+
+ default:
+ return SSB_UNKNOWN;
+
+ /* Fail for a valid opcode that implies no starting bits. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_ALLANY:
+ case OP_ANY:
+ case OP_ANYBYTE:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_COND:
+ case OP_CREF:
+ case OP_FALSE:
+ case OP_TRUE:
+ case OP_DNCREF:
+ case OP_DNREF:
+ case OP_DNREFI:
+ case OP_DNRREF:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_END:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_EXTUNI:
+ case OP_FAIL:
+ case OP_MARK:
+ case OP_NOT:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ case OP_NOTI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_NOTPROP:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOT_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_RECURSE:
+ case OP_REF:
+ case OP_REFI:
+ case OP_REVERSE:
+ case OP_RREF:
+ case OP_SCOND:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_THEN:
+ case OP_THEN_ARG:
+ return SSB_FAIL;
+
+ /* A "real" property test implies no starting bits, but the fake property
+ PT_CLIST identifies a list of characters. These lists are short, as they
+ are used for characters with more than one "other case", so there is no
+ point in recognizing them for OP_NOTPROP. */
+
+ case OP_PROP:
+ if (tcode[1] != PT_CLIST) return SSB_FAIL;
+ {
+ const uint32_t *p = PRIV(ucd_caseless_sets) + tcode[2];
+ while ((c = *p++) < NOTACHAR)
+ {
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (utf)
+ {
+ PCRE2_UCHAR buff[6];
+ (void)PRIV(ord2utf)(c, buff);
+ c = buff[0];
+ }
+#endif
+ if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
+ }
+ }
+ try_next = FALSE;
+ break;
+
+ /* We can ignore word boundary tests. */
+
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ tcode++;
+ break;
+
+ /* If we hit a bracket or a positive lookahead assertion, recurse to set
+ bits from within the subpattern. If it can't find anything, we have to
+ give up. If it finds some mandatory character(s), we are done for this
+ branch. Otherwise, carry on scanning after the subpattern. */
+
+ case OP_BRA:
+ case OP_SBRA:
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_ASSERT:
+ rc = set_start_bits(re, tcode, utf);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
+ if (rc == SSB_DONE) try_next = FALSE; else
+ {
+ do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ }
+ break;
+
+ /* If we hit ALT or KET, it means we haven't found anything mandatory in
+ this branch, though we might have found something optional. For ALT, we
+ continue with the next alternative, but we have to arrange that the final
+ result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
+ return SSB_CONTINUE: if this is the top level, that indicates failure,
+ but after a nested subpattern, it causes scanning to continue. */
+
+ case OP_ALT:
+ yield = SSB_CONTINUE;
+ try_next = FALSE;
+ break;
+
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ return SSB_CONTINUE;
+
+ /* Skip over callout */
+
+ case OP_CALLOUT:
+ tcode += PRIV(OP_lengths)[OP_CALLOUT];
+ break;
+
+ case OP_CALLOUT_STR:
+ tcode += GET(tcode, 1 + 2*LINK_SIZE);
+ break;
+
+ /* Skip over lookbehind and negative lookahead assertions */
+
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* BRAZERO does the bracket, but carries on. */
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ rc = set_start_bits(re, ++tcode, utf);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
+ do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* SKIPZERO skips the bracket. */
+
+ case OP_SKIPZERO:
+ tcode++;
+ do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* Single-char * or ? sets the bit and tries the next item */
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ tcode = set_table_bit(re, tcode + 1, FALSE, utf);
+ break;
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ tcode = set_table_bit(re, tcode + 1, TRUE, utf);
+ break;
+
+ /* Single-char upto sets the bit and tries the next */
+
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf);
+ break;
+
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf);
+ break;
+
+ /* At least one single char sets the bit and stops */
+
+ case OP_EXACT:
+ tcode += IMM2_SIZE;
+ /* Fall through */
+ case OP_CHAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ (void)set_table_bit(re, tcode + 1, FALSE, utf);
+ try_next = FALSE;
+ break;
+
+ case OP_EXACTI:
+ tcode += IMM2_SIZE;
+ /* Fall through */
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ (void)set_table_bit(re, tcode + 1, TRUE, utf);
+ try_next = FALSE;
+ break;
+
+ /* Special spacing and line-terminating items. These recognize specific
+ lists of characters. The difference between VSPACE and ANYNL is that the
+ latter can match the two-character CRLF sequence, but that is not
+ relevant for finding the first character, so their code here is
+ identical. */
+
+ case OP_HSPACE:
+ SET_BIT(CHAR_HT);
+ SET_BIT(CHAR_SPACE);
+
+ /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
+ the bits for 0xA0 and for code units >= 255, independently of UTF. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ SET_BIT(0xA0);
+ SET_BIT(0xFF);
+#else
+ /* For the 8-bit library in UTF-8 mode, set the bits for the first code
+ units of horizontal space characters. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ SET_BIT(0xC2); /* For U+00A0 */
+ SET_BIT(0xE1); /* For U+1680, U+180E */
+ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
+ SET_BIT(0xE3); /* For U+3000 */
+ }
+ else
+#endif
+ /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless
+ the code is EBCDIC. */
+ {
+#ifndef EBCDIC
+ SET_BIT(0xA0);
+#endif /* Not EBCDIC */
+ }
+#endif /* 8-bit support */
+
+ try_next = FALSE;
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ SET_BIT(CHAR_LF);
+ SET_BIT(CHAR_VT);
+ SET_BIT(CHAR_FF);
+ SET_BIT(CHAR_CR);
+
+ /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
+ the bits for NEL and for code units >= 255, independently of UTF. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ SET_BIT(CHAR_NEL);
+ SET_BIT(0xFF);
+#else
+ /* For the 8-bit library in UTF-8 mode, set the bits for the first code
+ units of vertical space characters. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ SET_BIT(0xC2); /* For U+0085 (NEL) */
+ SET_BIT(0xE2); /* For U+2028, U+2029 */
+ }
+ else
+#endif
+ /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */
+ {
+ SET_BIT(CHAR_NEL);
+ }
+#endif /* 8-bit support */
+
+ try_next = FALSE;
+ break;
+
+ /* Single character types set the bits and stop. Note that if PCRE2_UCP
+ is set, we do not see these op codes because \d etc are converted to
+ properties. Therefore, these apply in the case when only characters less
+ than 256 are recognized to match the types. */
+
+ case OP_NOT_DIGIT:
+ set_nottype_bits(re, cbit_digit, table_limit);
+ try_next = FALSE;
+ break;
+
+ case OP_DIGIT:
+ set_type_bits(re, cbit_digit, table_limit);
+ try_next = FALSE;
+ break;
+
+ case OP_NOT_WHITESPACE:
+ set_nottype_bits(re, cbit_space, table_limit);
+ try_next = FALSE;
+ break;
+
+ case OP_WHITESPACE:
+ set_type_bits(re, cbit_space, table_limit);
+ try_next = FALSE;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ set_nottype_bits(re, cbit_word, table_limit);
+ try_next = FALSE;
+ break;
+
+ case OP_WORDCHAR:
+ set_type_bits(re, cbit_word, table_limit);
+ try_next = FALSE;
+ break;
+
+ /* One or more character type fudges the pointer and restarts, knowing
+ it will hit a single character type and stop there. */
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ tcode++;
+ break;
+
+ case OP_TYPEEXACT:
+ tcode += 1 + IMM2_SIZE;
+ break;
+
+ /* Zero or more repeats of character types set the bits and then
+ try again. */
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ tcode += IMM2_SIZE; /* Fall through */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ switch(tcode[1])
+ {
+ default:
+ case OP_ANY:
+ case OP_ALLANY:
+ return SSB_FAIL;
+
+ case OP_HSPACE:
+ SET_BIT(CHAR_HT);
+ SET_BIT(CHAR_SPACE);
+
+ /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
+ the bits for 0xA0 and for code units >= 255, independently of UTF. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ SET_BIT(0xA0);
+ SET_BIT(0xFF);
+#else
+ /* For the 8-bit library in UTF-8 mode, set the bits for the first code
+ units of horizontal space characters. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ SET_BIT(0xC2); /* For U+00A0 */
+ SET_BIT(0xE1); /* For U+1680, U+180E */
+ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
+ SET_BIT(0xE3); /* For U+3000 */
+ }
+ else
+#endif
+ /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless
+ the code is EBCDIC. */
+ {
+#ifndef EBCDIC
+ SET_BIT(0xA0);
+#endif /* Not EBCDIC */
+ }
+#endif /* 8-bit support */
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ SET_BIT(CHAR_LF);
+ SET_BIT(CHAR_VT);
+ SET_BIT(CHAR_FF);
+ SET_BIT(CHAR_CR);
+
+ /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
+ the bits for NEL and for code units >= 255, independently of UTF. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ SET_BIT(CHAR_NEL);
+ SET_BIT(0xFF);
+#else
+ /* For the 8-bit library in UTF-8 mode, set the bits for the first code
+ units of vertical space characters. */
+
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ SET_BIT(0xC2); /* For U+0085 (NEL) */
+ SET_BIT(0xE2); /* For U+2028, U+2029 */
+ }
+ else
+#endif
+ /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */
+ {
+ SET_BIT(CHAR_NEL);
+ }
+#endif /* 8-bit support */
+ break;
+
+ case OP_NOT_DIGIT:
+ set_nottype_bits(re, cbit_digit, table_limit);
+ break;
+
+ case OP_DIGIT:
+ set_type_bits(re, cbit_digit, table_limit);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ set_nottype_bits(re, cbit_space, table_limit);
+ break;
+
+ case OP_WHITESPACE:
+ set_type_bits(re, cbit_space, table_limit);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ set_nottype_bits(re, cbit_word, table_limit);
+ break;
+
+ case OP_WORDCHAR:
+ set_type_bits(re, cbit_word, table_limit);
+ break;
+ }
+
+ tcode += 2;
+ break;
+
+ /* Extended class: if there are any property checks, or if this is a
+ negative XCLASS without a map, give up. If there are no property checks,
+ there must be wide characters on the XCLASS list, because otherwise an
+ XCLASS would not have been created. This means that code points >= 255
+ are always potential starters. */
+
+#ifdef SUPPORT_WIDE_CHARS
+ case OP_XCLASS:
+ if ((tcode[1 + LINK_SIZE] & XCL_HASPROP) != 0 ||
+ (tcode[1 + LINK_SIZE] & (XCL_MAP|XCL_NOT)) == XCL_NOT)
+ return SSB_FAIL;
+
+ /* We have a positive XCLASS or a negative one without a map. Set up the
+ map pointer if there is one, and fall through. */
+
+ classmap = ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0)? NULL :
+ (uint8_t *)(tcode + 1 + LINK_SIZE + 1);
+#endif
+
+ /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are
+ in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter
+ because it starts a character with a value > 255. In 8-bit non-UTF mode,
+ there is no difference between CLASS and NCLASS. In all other wide
+ character modes, set the 0xFF bit to indicate code units >= 255. */
+
+ case OP_NCLASS:
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (utf)
+ {
+ re->start_bitmap[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
+ memset(re->start_bitmap+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
+ }
+#elif PCRE2_CODE_UNIT_WIDTH != 8
+ SET_BIT(0xFF); /* For characters >= 255 */
+#endif
+ /* Fall through */
+
+ /* Enter here for a positive non-XCLASS. If we have fallen through from
+ an XCLASS, classmap will already be set; just advance the code pointer.
+ Otherwise, set up classmap for a a non-XCLASS and advance past it. */
+
+ case OP_CLASS:
+ if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else
+ {
+ classmap = (uint8_t *)(++tcode);
+ tcode += 32 / sizeof(PCRE2_UCHAR);
+ }
+
+ /* When wide characters are supported, classmap may be NULL. In UTF-8
+ (sic) mode, the bits in a class bit map correspond to character values,
+ not to byte values. However, the bit map we are constructing is for byte
+ values. So we have to do a conversion for characters whose code point is
+ greater than 127. In fact, there are only two possible starting bytes for
+ characters in the range 128 - 255. */
+
+ if (classmap != NULL)
+ {
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
+ if (utf)
+ {
+ for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c];
+ for (c = 128; c < 256; c++)
+ {
+ if ((classmap[c/8] & (1 << (c&7))) != 0)
+ {
+ int d = (c >> 6) | 0xc0; /* Set bit for this starter */
+ re->start_bitmap[d/8] |= (1 << (d&7)); /* and then skip on to the */
+ c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
+ }
+ }
+ }
+ else
+#endif
+ /* In all modes except UTF-8, the two bit maps are compatible. */
+
+ {
+ for (c = 0; c < 32; c++) re->start_bitmap[c] |= classmap[c];
+ }
+ }
+
+ /* Act on what follows the class. For a zero minimum repeat, continue;
+ otherwise stop processing. */
+
+ switch (*tcode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
+ tcode++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
+ else try_next = FALSE;
+ break;
+
+ default:
+ try_next = FALSE;
+ break;
+ }
+ break; /* End of class handling case */
+ } /* End of switch for opcodes */
+ } /* End of try_next loop */
+
+ code += GET(code, 1); /* Advance to next branch */
+ }
+while (*code == OP_ALT);
+
+return yield;
+}
+
+
+
+/*************************************************
+* Study a compiled expression *
+*************************************************/
+
+/* This function is handed a compiled expression that it must study to produce
+information that will speed up the matching.
+
+Argument: points to the compiled expression
+Returns: 0 normally; non-zero should never normally occur
+ 1 unknown opcode in set_start_bits
+ 2 missing capturing bracket
+ 3 unknown opcode in find_minlength
+*/
+
+int
+PRIV(study)(pcre2_real_code *re)
+{
+int min;
+int count = 0;
+PCRE2_UCHAR *code;
+BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
+
+/* Find start of compiled code */
+
+code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
+ re->name_entry_size * re->name_count;
+
+/* For an anchored pattern, or an unanchored pattern that has a first code
+unit, or a multiline pattern that matches only at "line start", there is no
+point in seeking a list of starting code units. */
+
+if ((re->overall_options & PCRE2_ANCHORED) == 0 &&
+ (re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
+ {
+ int rc = set_start_bits(re, code, utf);
+ if (rc == SSB_UNKNOWN) return 1;
+ if (rc == SSB_DONE) re->flags |= PCRE2_FIRSTMAPSET;
+ }
+
+/* Find the minimum length of subject string. If the pattern can match an empty
+string, the minimum length is already known. If there are more back references
+than the size of the vector we are going to cache them in, do nothing. A
+pattern that complicated will probably take a long time to analyze and may in
+any case turn out to be too complicated. Note that back reference minima are
+held as 16-bit numbers. */
+
+if ((re->flags & PCRE2_MATCH_EMPTY) == 0 &&
+ re->top_backref <= MAX_CACHE_BACKREF)
+ {
+ int backref_cache[MAX_CACHE_BACKREF+1];
+ backref_cache[0] = 0; /* Highest one that is set */
+ min = find_minlength(re, code, code, utf, NULL, &count, backref_cache);
+ switch(min)
+ {
+ case -1: /* \C in UTF mode or (*ACCEPT) or over-complex regex */
+ break; /* Leave minlength unchanged (will be zero) */
+
+ case -2:
+ return 2; /* missing capturing bracket */
+
+ case -3:
+ return 3; /* unrecognized opcode */
+
+ default:
+ if (min > UINT16_MAX) min = UINT16_MAX;
+ re->minlength = min;
+ break;
+ }
+ }
+
+return 0;
+}
+
+/* End of pcre2_study.c */
diff --git a/thirdparty/pcre2/src/pcre2_substitute.c b/thirdparty/pcre2/src/pcre2_substitute.c
new file mode 100644
index 0000000000..8da951fc6e
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_substitute.c
@@ -0,0 +1,858 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+#define PTR_STACK_SIZE 20
+
+#define SUBSTITUTE_OPTIONS \
+ (PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \
+ PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_UNKNOWN_UNSET| \
+ PCRE2_SUBSTITUTE_UNSET_EMPTY)
+
+
+
+/*************************************************
+* Find end of substitute text *
+*************************************************/
+
+/* In extended mode, we recognize ${name:+set text:unset text} and similar
+constructions. This requires the identification of unescaped : and }
+characters. This function scans for such. It must deal with nested ${
+constructions. The pointer to the text is updated, either to the required end
+character, or to where an error was detected.
+
+Arguments:
+ code points to the compiled expression (for options)
+ ptrptr points to the pointer to the start of the text (updated)
+ ptrend end of the whole string
+ last TRUE if the last expected string (only } recognized)
+
+Returns: 0 on success
+ negative error code on failure
+*/
+
+static int
+find_text_end(const pcre2_code *code, PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend,
+ BOOL last)
+{
+int rc = 0;
+uint32_t nestlevel = 0;
+BOOL literal = FALSE;
+PCRE2_SPTR ptr = *ptrptr;
+
+for (; ptr < ptrend; ptr++)
+ {
+ if (literal)
+ {
+ if (ptr[0] == CHAR_BACKSLASH && ptr < ptrend - 1 && ptr[1] == CHAR_E)
+ {
+ literal = FALSE;
+ ptr += 1;
+ }
+ }
+
+ else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (nestlevel == 0) goto EXIT;
+ nestlevel--;
+ }
+
+ else if (*ptr == CHAR_COLON && !last && nestlevel == 0) goto EXIT;
+
+ else if (*ptr == CHAR_DOLLAR_SIGN)
+ {
+ if (ptr < ptrend - 1 && ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+ {
+ nestlevel++;
+ ptr += 1;
+ }
+ }
+
+ else if (*ptr == CHAR_BACKSLASH)
+ {
+ int erc;
+ int errorcode;
+ uint32_t ch;
+
+ if (ptr < ptrend - 1) switch (ptr[1])
+ {
+ case CHAR_L:
+ case CHAR_l:
+ case CHAR_U:
+ case CHAR_u:
+ ptr += 1;
+ continue;
+ }
+
+ ptr += 1; /* Must point after \ */
+ erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode,
+ code->overall_options, FALSE, NULL);
+ ptr -= 1; /* Back to last code unit of escape */
+ if (errorcode != 0)
+ {
+ rc = errorcode;
+ goto EXIT;
+ }
+
+ switch(erc)
+ {
+ case 0: /* Data character */
+ case ESC_E: /* Isolated \E is ignored */
+ break;
+
+ case ESC_Q:
+ literal = TRUE;
+ break;
+
+ default:
+ rc = PCRE2_ERROR_BADREPESCAPE;
+ goto EXIT;
+ }
+ }
+ }
+
+rc = PCRE2_ERROR_REPMISSINGBRACE; /* Terminator not found */
+
+EXIT:
+*ptrptr = ptr;
+return rc;
+}
+
+
+
+/*************************************************
+* Match and substitute *
+*************************************************/
+
+/* This function applies a compiled re to a subject string and creates a new
+string with substitutions. The first 7 arguments are the same as for
+pcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED.
+
+Arguments:
+ code points to the compiled expression
+ subject points to the subject string
+ length length of subject string (may contain binary zeros)
+ start_offset where to start in the subject string
+ options option bits
+ match_data points to a match_data block, or is NULL
+ context points a PCRE2 context
+ replacement points to the replacement string
+ rlength length of replacement string
+ buffer where to put the substituted string
+ blength points to length of buffer; updated to length of string
+
+Returns: >= 0 number of substitutions made
+ < 0 an error code
+ PCRE2_ERROR_BADREPLACEMENT means invalid use of $
+*/
+
+/* This macro checks for space in the buffer before copying into it. On
+overflow, either give an error immediately, or keep on, accumulating the
+length. */
+
+#define CHECKMEMCPY(from,length) \
+ if (!overflowed && lengthleft < length) \
+ { \
+ if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \
+ overflowed = TRUE; \
+ extra_needed = length - lengthleft; \
+ } \
+ else if (overflowed) \
+ { \
+ extra_needed += length; \
+ } \
+ else \
+ { \
+ memcpy(buffer + buff_offset, from, CU2BYTES(length)); \
+ buff_offset += length; \
+ lengthleft -= length; \
+ }
+
+/* Here's the function */
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
+ PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
+ pcre2_match_context *mcontext, PCRE2_SPTR replacement, PCRE2_SIZE rlength,
+ PCRE2_UCHAR *buffer, PCRE2_SIZE *blength)
+{
+int rc;
+int subs;
+int forcecase = 0;
+int forcecasereset = 0;
+uint32_t ovector_count;
+uint32_t goptions = 0;
+uint32_t suboptions;
+BOOL match_data_created = FALSE;
+BOOL literal = FALSE;
+BOOL overflowed = FALSE;
+#ifdef SUPPORT_UNICODE
+BOOL utf = (code->overall_options & PCRE2_UTF) != 0;
+#endif
+PCRE2_UCHAR temp[6];
+PCRE2_SPTR ptr;
+PCRE2_SPTR repend;
+PCRE2_SIZE extra_needed = 0;
+PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength;
+PCRE2_SIZE *ovector;
+
+buff_offset = 0;
+lengthleft = buff_length = *blength;
+*blength = PCRE2_UNSET;
+
+/* Partial matching is not valid. */
+
+if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)
+ return PCRE2_ERROR_BADOPTION;
+
+/* If no match data block is provided, create one. */
+
+if (match_data == NULL)
+ {
+ pcre2_general_context *gcontext = (mcontext == NULL)?
+ (pcre2_general_context *)code :
+ (pcre2_general_context *)mcontext;
+ match_data = pcre2_match_data_create_from_pattern(code, gcontext);
+ if (match_data == NULL) return PCRE2_ERROR_NOMEMORY;
+ match_data_created = TRUE;
+ }
+ovector = pcre2_get_ovector_pointer(match_data);
+ovector_count = pcre2_get_ovector_count(match_data);
+
+/* Find lengths of zero-terminated strings and the end of the replacement. */
+
+if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject);
+if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement);
+repend = replacement + rlength;
+
+/* Check UTF replacement string if necessary. */
+
+#ifdef SUPPORT_UNICODE
+if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
+ {
+ rc = PRIV(valid_utf)(replacement, rlength, &(match_data->rightchar));
+ if (rc != 0)
+ {
+ match_data->leftchar = 0;
+ goto EXIT;
+ }
+ }
+#endif /* SUPPORT_UNICODE */
+
+/* Save the substitute options and remove them from the match options. */
+
+suboptions = options & SUBSTITUTE_OPTIONS;
+options &= ~SUBSTITUTE_OPTIONS;
+
+/* Copy up to the start offset */
+
+if (start_offset > length)
+ {
+ match_data->leftchar = 0;
+ rc = PCRE2_ERROR_BADOFFSET;
+ goto EXIT;
+ }
+CHECKMEMCPY(subject, start_offset);
+
+/* Loop for global substituting. */
+
+subs = 0;
+do
+ {
+ PCRE2_SPTR ptrstack[PTR_STACK_SIZE];
+ uint32_t ptrstackptr = 0;
+
+ rc = pcre2_match(code, subject, length, start_offset, options|goptions,
+ match_data, mcontext);
+
+#ifdef SUPPORT_UNICODE
+ if (utf) options |= PCRE2_NO_UTF_CHECK; /* Only need to check once */
+#endif
+
+ /* Any error other than no match returns the error code. No match when not
+ doing the special after-empty-match global rematch, or when at the end of the
+ subject, breaks the global loop. Otherwise, advance the starting point by one
+ character, copying it to the output, and try again. */
+
+ if (rc < 0)
+ {
+ PCRE2_SIZE save_start;
+
+ if (rc != PCRE2_ERROR_NOMATCH) goto EXIT;
+ if (goptions == 0 || start_offset >= length) break;
+
+ /* Advance by one code point. Then, if CRLF is a valid newline sequence and
+ we have advanced into the middle of it, advance one more code point. In
+ other words, do not start in the middle of CRLF, even if CR and LF on their
+ own are valid newlines. */
+
+ save_start = start_offset++;
+ if (subject[start_offset-1] == CHAR_CR &&
+ code->newline_convention != PCRE2_NEWLINE_CR &&
+ code->newline_convention != PCRE2_NEWLINE_LF &&
+ start_offset < length &&
+ subject[start_offset] == CHAR_LF)
+ start_offset++;
+
+ /* Otherwise, in UTF mode, advance past any secondary code points. */
+
+ else if ((code->overall_options & PCRE2_UTF) != 0)
+ {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ while (start_offset < length && (subject[start_offset] & 0xc0) == 0x80)
+ start_offset++;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ while (start_offset < length &&
+ (subject[start_offset] & 0xfc00) == 0xdc00)
+ start_offset++;
+#endif
+ }
+
+ /* Copy what we have advanced past, reset the special global options, and
+ continue to the next match. */
+
+ fraglength = start_offset - save_start;
+ CHECKMEMCPY(subject + save_start, fraglength);
+ goptions = 0;
+ continue;
+ }
+
+ /* Handle a successful match. Matches that use \K to end before they start
+ are not supported. */
+
+ if (ovector[1] < ovector[0])
+ {
+ rc = PCRE2_ERROR_BADSUBSPATTERN;
+ goto EXIT;
+ }
+
+ /* Count substitutions with a paranoid check for integer overflow; surely no
+ real call to this function would ever hit this! */
+
+ if (subs == INT_MAX)
+ {
+ rc = PCRE2_ERROR_TOOMANYREPLACE;
+ goto EXIT;
+ }
+ subs++;
+
+ /* Copy the text leading up to the match. */
+
+ if (rc == 0) rc = ovector_count;
+ fraglength = ovector[0] - start_offset;
+ CHECKMEMCPY(subject + start_offset, fraglength);
+
+ /* Process the replacement string. Literal mode is set by \Q, but only in
+ extended mode when backslashes are being interpreted. In extended mode we
+ must handle nested substrings that are to be reprocessed. */
+
+ ptr = replacement;
+ for (;;)
+ {
+ uint32_t ch;
+ unsigned int chlen;
+
+ /* If at the end of a nested substring, pop the stack. */
+
+ if (ptr >= repend)
+ {
+ if (ptrstackptr <= 0) break; /* End of replacement string */
+ repend = ptrstack[--ptrstackptr];
+ ptr = ptrstack[--ptrstackptr];
+ continue;
+ }
+
+ /* Handle the next character */
+
+ if (literal)
+ {
+ if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E)
+ {
+ literal = FALSE;
+ ptr += 2;
+ continue;
+ }
+ goto LOADLITERAL;
+ }
+
+ /* Not in literal mode. */
+
+ if (*ptr == CHAR_DOLLAR_SIGN)
+ {
+ int group, n;
+ uint32_t special = 0;
+ BOOL inparens;
+ BOOL star;
+ PCRE2_SIZE sublength;
+ PCRE2_SPTR text1_start = NULL;
+ PCRE2_SPTR text1_end = NULL;
+ PCRE2_SPTR text2_start = NULL;
+ PCRE2_SPTR text2_end = NULL;
+ PCRE2_UCHAR next;
+ PCRE2_UCHAR name[33];
+
+ if (++ptr >= repend) goto BAD;
+ if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL;
+
+ group = -1;
+ n = 0;
+ inparens = FALSE;
+ star = FALSE;
+
+ if (next == CHAR_LEFT_CURLY_BRACKET)
+ {
+ if (++ptr >= repend) goto BAD;
+ next = *ptr;
+ inparens = TRUE;
+ }
+
+ if (next == CHAR_ASTERISK)
+ {
+ if (++ptr >= repend) goto BAD;
+ next = *ptr;
+ star = TRUE;
+ }
+
+ if (!star && next >= CHAR_0 && next <= CHAR_9)
+ {
+ group = next - CHAR_0;
+ while (++ptr < repend)
+ {
+ next = *ptr;
+ if (next < CHAR_0 || next > CHAR_9) break;
+ group = group * 10 + next - CHAR_0;
+
+ /* A check for a number greater than the hightest captured group
+ is sufficient here; no need for a separate overflow check. If unknown
+ groups are to be treated as unset, just skip over any remaining
+ digits and carry on. */
+
+ if (group > code->top_bracket)
+ {
+ if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)
+ {
+ while (++ptr < repend && *ptr >= CHAR_0 && *ptr <= CHAR_9);
+ break;
+ }
+ else
+ {
+ rc = PCRE2_ERROR_NOSUBSTRING;
+ goto PTREXIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ const uint8_t *ctypes = code->tables + ctypes_offset;
+ while (MAX_255(next) && (ctypes[next] & ctype_word) != 0)
+ {
+ name[n++] = next;
+ if (n > 32) goto BAD;
+ if (++ptr >= repend) break;
+ next = *ptr;
+ }
+ if (n == 0) goto BAD;
+ name[n] = 0;
+ }
+
+ /* In extended mode we recognize ${name:+set text:unset text} and
+ ${name:-default text}. */
+
+ if (inparens)
+ {
+ if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&
+ !star && ptr < repend - 2 && next == CHAR_COLON)
+ {
+ special = *(++ptr);
+ if (special != CHAR_PLUS && special != CHAR_MINUS)
+ {
+ rc = PCRE2_ERROR_BADSUBSTITUTION;
+ goto PTREXIT;
+ }
+
+ text1_start = ++ptr;
+ rc = find_text_end(code, &ptr, repend, special == CHAR_MINUS);
+ if (rc != 0) goto PTREXIT;
+ text1_end = ptr;
+
+ if (special == CHAR_PLUS && *ptr == CHAR_COLON)
+ {
+ text2_start = ++ptr;
+ rc = find_text_end(code, &ptr, repend, TRUE);
+ if (rc != 0) goto PTREXIT;
+ text2_end = ptr;
+ }
+ }
+
+ else
+ {
+ if (ptr >= repend || *ptr != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ rc = PCRE2_ERROR_REPMISSINGBRACE;
+ goto PTREXIT;
+ }
+ }
+
+ ptr++;
+ }
+
+ /* Have found a syntactically correct group number or name, or *name.
+ Only *MARK is currently recognized. */
+
+ if (star)
+ {
+ if (PRIV(strcmp_c8)(name, STRING_MARK) == 0)
+ {
+ PCRE2_SPTR mark = pcre2_get_mark(match_data);
+ if (mark != NULL)
+ {
+ PCRE2_SPTR mark_start = mark;
+ while (*mark != 0) mark++;
+ fraglength = mark - mark_start;
+ CHECKMEMCPY(mark_start, fraglength);
+ }
+ }
+ else goto BAD;
+ }
+
+ /* Substitute the contents of a group. We don't use substring_copy
+ functions any more, in order to support case forcing. */
+
+ else
+ {
+ PCRE2_SPTR subptr, subptrend;
+
+ /* Find a number for a named group. In case there are duplicate names,
+ search for the first one that is set. If the name is not found when
+ PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a
+ non-existent group. */
+
+ if (group < 0)
+ {
+ PCRE2_SPTR first, last, entry;
+ rc = pcre2_substring_nametable_scan(code, name, &first, &last);
+ if (rc == PCRE2_ERROR_NOSUBSTRING &&
+ (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)
+ {
+ group = code->top_bracket + 1;
+ }
+ else
+ {
+ if (rc < 0) goto PTREXIT;
+ for (entry = first; entry <= last; entry += rc)
+ {
+ uint32_t ng = GET2(entry, 0);
+ if (ng < ovector_count)
+ {
+ if (group < 0) group = ng; /* First in ovector */
+ if (ovector[ng*2] != PCRE2_UNSET)
+ {
+ group = ng; /* First that is set */
+ break;
+ }
+ }
+ }
+
+ /* If group is still negative, it means we did not find a group
+ that is in the ovector. Just set the first group. */
+
+ if (group < 0) group = GET2(first, 0);
+ }
+ }
+
+ /* We now have a group that is identified by number. Find the length of
+ the captured string. If a group in a non-special substitution is unset
+ when PCRE2_SUBSTITUTE_UNSET_EMPTY is set, substitute nothing. */
+
+ rc = pcre2_substring_length_bynumber(match_data, group, &sublength);
+ if (rc < 0)
+ {
+ if (rc == PCRE2_ERROR_NOSUBSTRING &&
+ (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)
+ {
+ rc = PCRE2_ERROR_UNSET;
+ }
+ if (rc != PCRE2_ERROR_UNSET) goto PTREXIT; /* Non-unset errors */
+ if (special == 0) /* Plain substitution */
+ {
+ if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue;
+ goto PTREXIT; /* Else error */
+ }
+ }
+
+ /* If special is '+' we have a 'set' and possibly an 'unset' text,
+ both of which are reprocessed when used. If special is '-' we have a
+ default text for when the group is unset; it must be reprocessed. */
+
+ if (special != 0)
+ {
+ if (special == CHAR_MINUS)
+ {
+ if (rc == 0) goto LITERAL_SUBSTITUTE;
+ text2_start = text1_start;
+ text2_end = text1_end;
+ }
+
+ if (ptrstackptr >= PTR_STACK_SIZE) goto BAD;
+ ptrstack[ptrstackptr++] = ptr;
+ ptrstack[ptrstackptr++] = repend;
+
+ if (rc == 0)
+ {
+ ptr = text1_start;
+ repend = text1_end;
+ }
+ else
+ {
+ ptr = text2_start;
+ repend = text2_end;
+ }
+ continue;
+ }
+
+ /* Otherwise we have a literal substitution of a group's contents. */
+
+ LITERAL_SUBSTITUTE:
+ subptr = subject + ovector[group*2];
+ subptrend = subject + ovector[group*2 + 1];
+
+ /* Substitute a literal string, possibly forcing alphabetic case. */
+
+ while (subptr < subptrend)
+ {
+ GETCHARINCTEST(ch, subptr);
+ if (forcecase != 0)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t type = UCD_CHARTYPE(ch);
+ if (PRIV(ucp_gentype)[type] == ucp_L &&
+ type != ((forcecase > 0)? ucp_Lu : ucp_Ll))
+ ch = UCD_OTHERCASE(ch);
+ }
+ else
+#endif
+ {
+ if (((code->tables + cbits_offset +
+ ((forcecase > 0)? cbit_upper:cbit_lower)
+ )[ch/8] & (1 << (ch%8))) == 0)
+ ch = (code->tables + fcc_offset)[ch];
+ }
+ forcecase = forcecasereset;
+ }
+
+#ifdef SUPPORT_UNICODE
+ if (utf) chlen = PRIV(ord2utf)(ch, temp); else
+#endif
+ {
+ temp[0] = ch;
+ chlen = 1;
+ }
+ CHECKMEMCPY(temp, chlen);
+ }
+ }
+ }
+
+ /* Handle an escape sequence in extended mode. We can use check_escape()
+ to process \Q, \E, \c, \o, \x and \ followed by non-alphanumerics, but
+ the case-forcing escapes are not supported in pcre2_compile() so must be
+ recognized here. */
+
+ else if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&
+ *ptr == CHAR_BACKSLASH)
+ {
+ int errorcode;
+
+ if (ptr < repend - 1) switch (ptr[1])
+ {
+ case CHAR_L:
+ forcecase = forcecasereset = -1;
+ ptr += 2;
+ continue;
+
+ case CHAR_l:
+ forcecase = -1;
+ forcecasereset = 0;
+ ptr += 2;
+ continue;
+
+ case CHAR_U:
+ forcecase = forcecasereset = 1;
+ ptr += 2;
+ continue;
+
+ case CHAR_u:
+ forcecase = 1;
+ forcecasereset = 0;
+ ptr += 2;
+ continue;
+
+ default:
+ break;
+ }
+
+ ptr++; /* Point after \ */
+ rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode,
+ code->overall_options, FALSE, NULL);
+ if (errorcode != 0) goto BADESCAPE;
+
+ switch(rc)
+ {
+ case ESC_E:
+ forcecase = forcecasereset = 0;
+ continue;
+
+ case ESC_Q:
+ literal = TRUE;
+ continue;
+
+ case 0: /* Data character */
+ goto LITERAL;
+
+ default:
+ goto BADESCAPE;
+ }
+ }
+
+ /* Handle a literal code unit */
+
+ else
+ {
+ LOADLITERAL:
+ GETCHARINCTEST(ch, ptr); /* Get character value, increment pointer */
+
+ LITERAL:
+ if (forcecase != 0)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ uint32_t type = UCD_CHARTYPE(ch);
+ if (PRIV(ucp_gentype)[type] == ucp_L &&
+ type != ((forcecase > 0)? ucp_Lu : ucp_Ll))
+ ch = UCD_OTHERCASE(ch);
+ }
+ else
+#endif
+ {
+ if (((code->tables + cbits_offset +
+ ((forcecase > 0)? cbit_upper:cbit_lower)
+ )[ch/8] & (1 << (ch%8))) == 0)
+ ch = (code->tables + fcc_offset)[ch];
+ }
+ forcecase = forcecasereset;
+ }
+
+#ifdef SUPPORT_UNICODE
+ if (utf) chlen = PRIV(ord2utf)(ch, temp); else
+#endif
+ {
+ temp[0] = ch;
+ chlen = 1;
+ }
+ CHECKMEMCPY(temp, chlen);
+ } /* End handling a literal code unit */
+ } /* End of loop for scanning the replacement. */
+
+ /* The replacement has been copied to the output. Update the start offset to
+ point to the rest of the subject string. If we matched an empty string,
+ do the magic for global matches. */
+
+ start_offset = ovector[1];
+ goptions = (ovector[0] != ovector[1])? 0 :
+ PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;
+ } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */
+
+/* Copy the rest of the subject. */
+
+fraglength = length - start_offset;
+CHECKMEMCPY(subject + start_offset, fraglength);
+temp[0] = 0;
+CHECKMEMCPY(temp , 1);
+
+/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set,
+and matching has carried on after a full buffer, in order to compute the length
+needed. Otherwise, an overflow generates an immediate error return. */
+
+if (overflowed)
+ {
+ rc = PCRE2_ERROR_NOMEMORY;
+ *blength = buff_length + extra_needed;
+ }
+
+/* After a successful execution, return the number of substitutions and set the
+length of buffer used, excluding the trailing zero. */
+
+else
+ {
+ rc = subs;
+ *blength = buff_offset - 1;
+ }
+
+EXIT:
+if (match_data_created) pcre2_match_data_free(match_data);
+ else match_data->rc = rc;
+return rc;
+
+NOROOM:
+rc = PCRE2_ERROR_NOMEMORY;
+goto EXIT;
+
+BAD:
+rc = PCRE2_ERROR_BADREPLACEMENT;
+goto PTREXIT;
+
+BADESCAPE:
+rc = PCRE2_ERROR_BADREPESCAPE;
+
+PTREXIT:
+*blength = (PCRE2_SIZE)(ptr - replacement);
+goto EXIT;
+}
+
+/* End of pcre2_substitute.c */
diff --git a/thirdparty/pcre2/src/pcre2_substring.c b/thirdparty/pcre2/src/pcre2_substring.c
new file mode 100644
index 0000000000..f6d7c39722
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_substring.c
@@ -0,0 +1,542 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+
+
+/*************************************************
+* Copy named captured string to given buffer *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer,
+identifying it by name. If the regex permits duplicate names, the first
+substring that is set is chosen.
+
+Arguments:
+ match_data points to the match data
+ stringname the name of the required substring
+ buffer where to put the substring
+ sizeptr the size of the buffer, updated to the size of the substring
+
+Returns: if successful: zero
+ if not successful, a negative error code:
+ (1) an error from nametable_scan()
+ (2) an error from copy_bynumber()
+ (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector
+ (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_copy_byname(pcre2_match_data *match_data, PCRE2_SPTR stringname,
+ PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)
+{
+PCRE2_SPTR first, last, entry;
+int failrc, entrysize;
+if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)
+ return PCRE2_ERROR_DFA_UFUNC;
+entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,
+ &first, &last);
+if (entrysize < 0) return entrysize;
+failrc = PCRE2_ERROR_UNAVAILABLE;
+for (entry = first; entry <= last; entry += entrysize)
+ {
+ uint32_t n = GET2(entry, 0);
+ if (n < match_data->oveccount)
+ {
+ if (match_data->ovector[n*2] != PCRE2_UNSET)
+ return pcre2_substring_copy_bynumber(match_data, n, buffer, sizeptr);
+ failrc = PCRE2_ERROR_UNSET;
+ }
+ }
+return failrc;
+}
+
+
+
+/*************************************************
+* Copy numbered captured string to given buffer *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer,
+identifying it by number.
+
+Arguments:
+ match_data points to the match data
+ stringnumber the number of the required substring
+ buffer where to put the substring
+ sizeptr the size of the buffer, updated to the size of the substring
+
+Returns: if successful: 0
+ if not successful, a negative error code:
+ PCRE2_ERROR_NOMEMORY: buffer too small
+ PCRE2_ERROR_NOSUBSTRING: no such substring
+ PCRE2_ERROR_UNAVAILABLE: ovector too small
+ PCRE2_ERROR_UNSET: substring is not set
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_copy_bynumber(pcre2_match_data *match_data,
+ uint32_t stringnumber, PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)
+{
+int rc;
+PCRE2_SIZE size;
+rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
+if (rc < 0) return rc;
+if (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY;
+memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],
+ CU2BYTES(size));
+buffer[size] = 0;
+*sizeptr = size;
+return 0;
+}
+
+
+
+/*************************************************
+* Extract named captured string *
+*************************************************/
+
+/* This function copies a single captured substring, identified by name, into
+new memory. If the regex permits duplicate names, the first substring that is
+set is chosen.
+
+Arguments:
+ match_data pointer to match_data
+ stringname the name of the required substring
+ stringptr where to put the pointer to the new memory
+ sizeptr where to put the length of the substring
+
+Returns: if successful: zero
+ if not successful, a negative value:
+ (1) an error from nametable_scan()
+ (2) an error from get_bynumber()
+ (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector
+ (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_get_byname(pcre2_match_data *match_data,
+ PCRE2_SPTR stringname, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)
+{
+PCRE2_SPTR first, last, entry;
+int failrc, entrysize;
+if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)
+ return PCRE2_ERROR_DFA_UFUNC;
+entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,
+ &first, &last);
+if (entrysize < 0) return entrysize;
+failrc = PCRE2_ERROR_UNAVAILABLE;
+for (entry = first; entry <= last; entry += entrysize)
+ {
+ uint32_t n = GET2(entry, 0);
+ if (n < match_data->oveccount)
+ {
+ if (match_data->ovector[n*2] != PCRE2_UNSET)
+ return pcre2_substring_get_bynumber(match_data, n, stringptr, sizeptr);
+ failrc = PCRE2_ERROR_UNSET;
+ }
+ }
+return failrc;
+}
+
+
+
+/*************************************************
+* Extract captured string to new memory *
+*************************************************/
+
+/* This function copies a single captured substring into a piece of new
+memory.
+
+Arguments:
+ match_data points to match data
+ stringnumber the number of the required substring
+ stringptr where to put a pointer to the new memory
+ sizeptr where to put the size of the substring
+
+Returns: if successful: 0
+ if not successful, a negative error code:
+ PCRE2_ERROR_NOMEMORY: failed to get memory
+ PCRE2_ERROR_NOSUBSTRING: no such substring
+ PCRE2_ERROR_UNAVAILABLE: ovector too small
+ PCRE2_ERROR_UNSET: substring is not set
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_get_bynumber(pcre2_match_data *match_data,
+ uint32_t stringnumber, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)
+{
+int rc;
+PCRE2_SIZE size;
+PCRE2_UCHAR *yield;
+rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
+if (rc < 0) return rc;
+yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
+ (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);
+if (yield == NULL) return PCRE2_ERROR_NOMEMORY;
+yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));
+memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
+ CU2BYTES(size));
+yield[size] = 0;
+*stringptr = yield;
+*sizeptr = size;
+return 0;
+}
+
+
+
+/*************************************************
+* Free memory obtained by get_substring *
+*************************************************/
+
+/*
+Argument: the result of a previous pcre2_substring_get_byxxx()
+Returns: nothing
+*/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_substring_free(PCRE2_UCHAR *string)
+{
+if (string != NULL)
+ {
+ pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl));
+ memctl->free(memctl, memctl->memory_data);
+ }
+}
+
+
+
+/*************************************************
+* Get length of a named substring *
+*************************************************/
+
+/* This function returns the length of a named captured substring. If the regex
+permits duplicate names, the first substring that is set is chosen.
+
+Arguments:
+ match_data pointer to match data
+ stringname the name of the required substring
+ sizeptr where to put the length
+
+Returns: 0 if successful, else a negative error number
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_length_byname(pcre2_match_data *match_data,
+ PCRE2_SPTR stringname, PCRE2_SIZE *sizeptr)
+{
+PCRE2_SPTR first, last, entry;
+int failrc, entrysize;
+if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)
+ return PCRE2_ERROR_DFA_UFUNC;
+entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,
+ &first, &last);
+if (entrysize < 0) return entrysize;
+failrc = PCRE2_ERROR_UNAVAILABLE;
+for (entry = first; entry <= last; entry += entrysize)
+ {
+ uint32_t n = GET2(entry, 0);
+ if (n < match_data->oveccount)
+ {
+ if (match_data->ovector[n*2] != PCRE2_UNSET)
+ return pcre2_substring_length_bynumber(match_data, n, sizeptr);
+ failrc = PCRE2_ERROR_UNSET;
+ }
+ }
+return failrc;
+}
+
+
+
+/*************************************************
+* Get length of a numbered substring *
+*************************************************/
+
+/* This function returns the length of a captured substring. If the start is
+beyond the end (which can happen when \K is used in an assertion), it sets the
+length to zero.
+
+Arguments:
+ match_data pointer to match data
+ stringnumber the number of the required substring
+ sizeptr where to put the length, if not NULL
+
+Returns: if successful: 0
+ if not successful, a negative error code:
+ PCRE2_ERROR_NOSUBSTRING: no such substring
+ PCRE2_ERROR_UNAVAILABLE: ovector is too small
+ PCRE2_ERROR_UNSET: substring is not set
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_length_bynumber(pcre2_match_data *match_data,
+ uint32_t stringnumber, PCRE2_SIZE *sizeptr)
+{
+PCRE2_SIZE left, right;
+int count = match_data->rc;
+if (count == PCRE2_ERROR_PARTIAL)
+ {
+ if (stringnumber > 0) return PCRE2_ERROR_PARTIAL;
+ count = 0;
+ }
+else if (count < 0) return count; /* Match failed */
+
+if (match_data->matchedby != PCRE2_MATCHEDBY_DFA_INTERPRETER)
+ {
+ if (stringnumber > match_data->code->top_bracket)
+ return PCRE2_ERROR_NOSUBSTRING;
+ if (stringnumber >= match_data->oveccount)
+ return PCRE2_ERROR_UNAVAILABLE;
+ if (match_data->ovector[stringnumber*2] == PCRE2_UNSET)
+ return PCRE2_ERROR_UNSET;
+ }
+else /* Matched using pcre2_dfa_match() */
+ {
+ if (stringnumber >= match_data->oveccount) return PCRE2_ERROR_UNAVAILABLE;
+ if (count != 0 && stringnumber >= (uint32_t)count) return PCRE2_ERROR_UNSET;
+ }
+
+left = match_data->ovector[stringnumber*2];
+right = match_data->ovector[stringnumber*2+1];
+if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left;
+return 0;
+}
+
+
+
+/*************************************************
+* Extract all captured strings to new memory *
+*************************************************/
+
+/* This function gets one chunk of memory and builds a list of pointers and all
+the captured substrings in it. A NULL pointer is put on the end of the list.
+The substrings are zero-terminated, but also, if the final argument is
+non-NULL, a list of lengths is also returned. This allows binary data to be
+handled.
+
+Arguments:
+ match_data points to the match data
+ listptr set to point to the list of pointers
+ lengthsptr set to point to the list of lengths (may be NULL)
+
+Returns: if successful: 0
+ if not successful, a negative error code:
+ PCRE2_ERROR_NOMEMORY: failed to get memory,
+ or a match failure code
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_list_get(pcre2_match_data *match_data, PCRE2_UCHAR ***listptr,
+ PCRE2_SIZE **lengthsptr)
+{
+int i, count, count2;
+PCRE2_SIZE size;
+PCRE2_SIZE *lensp;
+pcre2_memctl *memp;
+PCRE2_UCHAR **listp;
+PCRE2_UCHAR *sp;
+PCRE2_SIZE *ovector;
+
+if ((count = match_data->rc) < 0) return count; /* Match failed */
+if (count == 0) count = match_data->oveccount; /* Ovector too small */
+
+count2 = 2*count;
+ovector = match_data->ovector;
+size = sizeof(pcre2_memctl) + sizeof(PCRE2_UCHAR *); /* For final NULL */
+if (lengthsptr != NULL) size += sizeof(PCRE2_SIZE) * count; /* For lengths */
+
+for (i = 0; i < count2; i += 2)
+ {
+ size += sizeof(PCRE2_UCHAR *) + CU2BYTES(1);
+ if (ovector[i+1] > ovector[i]) size += CU2BYTES(ovector[i+1] - ovector[i]);
+ }
+
+memp = PRIV(memctl_malloc)(size, (pcre2_memctl *)match_data);
+if (memp == NULL) return PCRE2_ERROR_NOMEMORY;
+
+*listptr = listp = (PCRE2_UCHAR **)((char *)memp + sizeof(pcre2_memctl));
+lensp = (PCRE2_SIZE *)((char *)listp + sizeof(PCRE2_UCHAR *) * (count + 1));
+
+if (lengthsptr == NULL)
+ {
+ sp = (PCRE2_UCHAR *)lensp;
+ lensp = NULL;
+ }
+else
+ {
+ *lengthsptr = lensp;
+ sp = (PCRE2_UCHAR *)((char *)lensp + sizeof(PCRE2_SIZE) * count);
+ }
+
+for (i = 0; i < count2; i += 2)
+ {
+ size = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0;
+ memcpy(sp, match_data->subject + ovector[i], CU2BYTES(size));
+ *listp++ = sp;
+ if (lensp != NULL) *lensp++ = size;
+ sp += size;
+ *sp++ = 0;
+ }
+
+*listp = NULL;
+return 0;
+}
+
+
+
+/*************************************************
+* Free memory obtained by substring_list_get *
+*************************************************/
+
+/*
+Argument: the result of a previous pcre2_substring_list_get()
+Returns: nothing
+*/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_substring_list_free(PCRE2_SPTR *list)
+{
+if (list != NULL)
+ {
+ pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl));
+ memctl->free(memctl, memctl->memory_data);
+ }
+}
+
+
+
+/*************************************************
+* Find (multiple) entries for named string *
+*************************************************/
+
+/* This function scans the nametable for a given name, using binary chop. It
+returns either two pointers to the entries in the table, or, if no pointers are
+given, the number of a unique group with the given name. If duplicate names are
+permitted, and the name is not unique, an error is generated.
+
+Arguments:
+ code the compiled regex
+ stringname the name whose entries required
+ firstptr where to put the pointer to the first entry
+ lastptr where to put the pointer to the last entry
+
+Returns: PCRE2_ERROR_NOSUBSTRING if the name is not found
+ otherwise, if firstptr and lastptr are NULL:
+ a group number for a unique substring
+ else PCRE2_ERROR_NOUNIQUESUBSTRING
+ otherwise:
+ the length of each entry, having set firstptr and lastptr
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname,
+ PCRE2_SPTR *firstptr, PCRE2_SPTR *lastptr)
+{
+uint16_t bot = 0;
+uint16_t top = code->name_count;
+uint16_t entrysize = code->name_entry_size;
+PCRE2_SPTR nametable = (PCRE2_SPTR)((char *)code + sizeof(pcre2_real_code));
+
+while (top > bot)
+ {
+ uint16_t mid = (top + bot) / 2;
+ PCRE2_SPTR entry = nametable + entrysize*mid;
+ int c = PRIV(strcmp)(stringname, entry + IMM2_SIZE);
+ if (c == 0)
+ {
+ PCRE2_SPTR first;
+ PCRE2_SPTR last;
+ PCRE2_SPTR lastentry;
+ lastentry = nametable + entrysize * (code->name_count - 1);
+ first = last = entry;
+ while (first > nametable)
+ {
+ if (PRIV(strcmp)(stringname, (first - entrysize + IMM2_SIZE)) != 0) break;
+ first -= entrysize;
+ }
+ while (last < lastentry)
+ {
+ if (PRIV(strcmp)(stringname, (last + entrysize + IMM2_SIZE)) != 0) break;
+ last += entrysize;
+ }
+ if (firstptr == NULL) return (first == last)?
+ (int)GET2(entry, 0) : PCRE2_ERROR_NOUNIQUESUBSTRING;
+ *firstptr = first;
+ *lastptr = last;
+ return entrysize;
+ }
+ if (c > 0) bot = mid + 1; else top = mid;
+ }
+
+return PCRE2_ERROR_NOSUBSTRING;
+}
+
+
+/*************************************************
+* Find number for named string *
+*************************************************/
+
+/* This function is a convenience wrapper for pcre2_substring_nametable_scan()
+when it is known that names are unique. If there are duplicate names, it is not
+defined which number is returned.
+
+Arguments:
+ code the compiled regex
+ stringname the name whose number is required
+
+Returns: the number of the named parenthesis, or a negative number
+ PCRE2_ERROR_NOSUBSTRING if not found
+ PCRE2_ERROR_NOUNIQUESUBSTRING if not unique
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_substring_number_from_name(const pcre2_code *code,
+ PCRE2_SPTR stringname)
+{
+return pcre2_substring_nametable_scan(code, stringname, NULL, NULL);
+}
+
+/* End of pcre2_substring.c */
diff --git a/thirdparty/pcre2/src/pcre2_tables.c b/thirdparty/pcre2/src/pcre2_tables.c
new file mode 100644
index 0000000000..b945ed7a7f
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_tables.c
@@ -0,0 +1,765 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This module contains some fixed tables that are used by more than one of the
+PCRE code modules. The tables are also #included by the pcre2test program,
+which uses macros to change their names from _pcre2_xxx to xxxx, thereby
+avoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is
+defined. */
+
+#ifndef PCRE2_PCRE2TEST /* We're compiling the library */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "pcre2_internal.h"
+#endif /* PCRE2_PCRE2TEST */
+
+
+/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
+the definition is next to the definition of the opcodes in pcre2_internal.h.
+This is mode-dependent, so is skipped when this file is included by pcre2test. */
+
+#ifndef PCRE2_PCRE2TEST
+const uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS };
+#endif
+
+/* Tables of horizontal and vertical whitespace characters, suitable for
+adding to classes. */
+
+const uint32_t PRIV(hspace_list)[] = { HSPACE_LIST };
+const uint32_t PRIV(vspace_list)[] = { VSPACE_LIST };
+
+/* These tables are the pairs of delimiters that are valid for callout string
+arguments. For each starting delimiter there must be a matching ending
+delimiter, which in fact is different only for bracket-like delimiters. */
+
+const uint32_t PRIV(callout_start_delims)[] = {
+ CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,
+ CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,
+ CHAR_DOLLAR_SIGN, CHAR_LEFT_CURLY_BRACKET, 0 };
+
+const uint32_t PRIV(callout_end_delims[]) = {
+ CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,
+ CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,
+ CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 };
+
+
+/*************************************************
+* Tables for UTF-8 support *
+*************************************************/
+
+/* These tables are required by pcre2test in 16- or 32-bit mode, as well
+as for the library in 8-bit mode, because pcre2test uses UTF-8 internally for
+handling wide characters. */
+
+#if defined PCRE2_PCRE2TEST || \
+ (defined SUPPORT_UNICODE && \
+ defined PCRE2_CODE_UNIT_WIDTH && \
+ PCRE2_CODE_UNIT_WIDTH == 8)
+
+/* These are the breakpoints for different numbers of bytes in a UTF-8
+character. */
+
+const int PRIV(utf8_table1)[] =
+ { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
+
+const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
+
+/* These are the indicator bits and the mask for the data bits to set in the
+first byte of a character, indexed by the number of additional bytes. */
+
+const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+
+/* Table of the number of extra bytes, indexed by the first byte masked with
+0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
+
+const uint8_t PRIV(utf8_table4)[] = {
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
+
+#endif /* UTF-8 support needed */
+
+
+#ifdef SUPPORT_UNICODE
+
+/* Table to translate from particular type value to the general value. */
+
+const uint32_t PRIV(ucp_gentype)[] = {
+ ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
+ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
+ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
+ ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
+ ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
+ ucp_P, ucp_P, /* Ps, Po */
+ ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
+ ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
+};
+
+/* This table encodes the rules for finding the end of an extended grapheme
+cluster. Every code point has a grapheme break property which is one of the
+ucp_gbXX values defined in pcre2_ucp.h. The 2-dimensional table is indexed by
+the properties of two adjacent code points. The left property selects a word
+from the table, and the right property selects a bit from that word like this:
+
+ PRIV(ucp_gbtable)[left-property] & (1 << right-property)
+
+The value is non-zero if a grapheme break is NOT permitted between the relevant
+two code points. The breaking rules are as follows:
+
+1. Break at the start and end of text (pretty obviously).
+
+2. Do not break between a CR and LF; otherwise, break before and after
+ controls.
+
+3. Do not break Hangul syllable sequences, the rules for which are:
+
+ L may be followed by L, V, LV or LVT
+ LV or V may be followed by V or T
+ LVT or T may be followed by T
+
+4. Do not break before extending characters.
+
+The next two rules are only for extended grapheme clusters (but that's what we
+are implementing).
+
+5. Do not break before SpacingMarks.
+
+6. Do not break after Prepend characters.
+
+7. Otherwise, break everywhere.
+*/
+
+const uint32_t PRIV(ucp_gbtable)[] = {
+ (1<<ucp_gbLF), /* 0 CR */
+ 0, /* 1 LF */
+ 0, /* 2 Control */
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark), /* 3 Extend */
+ (1<<ucp_gbExtend)|(1<<ucp_gbPrepend)| /* 4 Prepend */
+ (1<<ucp_gbSpacingMark)|(1<<ucp_gbL)|
+ (1<<ucp_gbV)|(1<<ucp_gbT)|(1<<ucp_gbLV)|
+ (1<<ucp_gbLVT)|(1<<ucp_gbOther),
+
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark), /* 5 SpacingMark */
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbL)| /* 6 L */
+ (1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbLV)|(1<<ucp_gbLVT),
+
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)| /* 7 V */
+ (1<<ucp_gbT),
+
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT), /* 8 T */
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)| /* 9 LV */
+ (1<<ucp_gbT),
+
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT), /* 10 LVT */
+ (1<<ucp_gbRegionalIndicator), /* 11 RegionalIndicator */
+ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark) /* 12 Other */
+};
+
+#ifdef SUPPORT_JIT
+/* This table reverses PRIV(ucp_gentype). We can save the cost
+of a memory load. */
+
+const int PRIV(ucp_typerange)[] = {
+ ucp_Cc, ucp_Cs,
+ ucp_Ll, ucp_Lu,
+ ucp_Mc, ucp_Mn,
+ ucp_Nd, ucp_No,
+ ucp_Pc, ucp_Ps,
+ ucp_Sc, ucp_So,
+ ucp_Zl, ucp_Zs,
+};
+#endif /* SUPPORT_JIT */
+
+/* The PRIV(utt)[] table below translates Unicode property names into type and
+code values. It is searched by binary chop, so must be in collating sequence of
+name. Originally, the table contained pointers to the name strings in the first
+field of each entry. However, that leads to a large number of relocations when
+a shared library is dynamically loaded. A significant reduction is made by
+putting all the names into a single, large string and then using offsets in the
+table itself. Maintenance is more error-prone, but frequent changes to this
+data are unlikely.
+
+July 2008: There is now a script called maint/GenerateUtt.py that can be used
+to generate this data automatically instead of maintaining it by hand.
+
+The script was updated in March 2009 to generate a new EBCDIC-compliant
+version. Like all other character and string literals that are compared against
+the regular expression pattern, we must use STR_ macros instead of literal
+strings to make sure that UTF-8 support works on EBCDIC platforms. */
+
+#define STRING_Ahom0 STR_A STR_h STR_o STR_m "\0"
+#define STRING_Anatolian_Hieroglyphs0 STR_A STR_n STR_a STR_t STR_o STR_l STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
+#define STRING_Any0 STR_A STR_n STR_y "\0"
+#define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0"
+#define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"
+#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
+#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
+#define STRING_Bassa_Vah0 STR_B STR_a STR_s STR_s STR_a STR_UNDERSCORE STR_V STR_a STR_h "\0"
+#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
+#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
+#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
+#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0"
+#define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
+#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"
+#define STRING_C0 STR_C "\0"
+#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
+#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
+#define STRING_Caucasian_Albanian0 STR_C STR_a STR_u STR_c STR_a STR_s STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_l STR_b STR_a STR_n STR_i STR_a STR_n "\0"
+#define STRING_Cc0 STR_C STR_c "\0"
+#define STRING_Cf0 STR_C STR_f "\0"
+#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"
+#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
+#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
+#define STRING_Cn0 STR_C STR_n "\0"
+#define STRING_Co0 STR_C STR_o "\0"
+#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
+#define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0"
+#define STRING_Cs0 STR_C STR_s "\0"
+#define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"
+#define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0"
+#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
+#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
+#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
+#define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0"
+#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
+#define STRING_Elbasan0 STR_E STR_l STR_b STR_a STR_s STR_a STR_n "\0"
+#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
+#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
+#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
+#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"
+#define STRING_Grantha0 STR_G STR_r STR_a STR_n STR_t STR_h STR_a "\0"
+#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"
+#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
+#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
+#define STRING_Han0 STR_H STR_a STR_n "\0"
+#define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0"
+#define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0"
+#define STRING_Hatran0 STR_H STR_a STR_t STR_r STR_a STR_n "\0"
+#define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0"
+#define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"
+#define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0"
+#define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"
+#define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
+#define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"
+#define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0"
+#define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0"
+#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
+#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
+#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
+#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
+#define STRING_Khojki0 STR_K STR_h STR_o STR_j STR_k STR_i "\0"
+#define STRING_Khudawadi0 STR_K STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0"
+#define STRING_L0 STR_L "\0"
+#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"
+#define STRING_Lao0 STR_L STR_a STR_o "\0"
+#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"
+#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"
+#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"
+#define STRING_Linear_A0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_A "\0"
+#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"
+#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"
+#define STRING_Ll0 STR_L STR_l "\0"
+#define STRING_Lm0 STR_L STR_m "\0"
+#define STRING_Lo0 STR_L STR_o "\0"
+#define STRING_Lt0 STR_L STR_t "\0"
+#define STRING_Lu0 STR_L STR_u "\0"
+#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"
+#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
+#define STRING_M0 STR_M "\0"
+#define STRING_Mahajani0 STR_M STR_a STR_h STR_a STR_j STR_a STR_n STR_i "\0"
+#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
+#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
+#define STRING_Manichaean0 STR_M STR_a STR_n STR_i STR_c STR_h STR_a STR_e STR_a STR_n "\0"
+#define STRING_Mc0 STR_M STR_c "\0"
+#define STRING_Me0 STR_M STR_e "\0"
+#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
+#define STRING_Mende_Kikakui0 STR_M STR_e STR_n STR_d STR_e STR_UNDERSCORE STR_K STR_i STR_k STR_a STR_k STR_u STR_i "\0"
+#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0"
+#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
+#define STRING_Miao0 STR_M STR_i STR_a STR_o "\0"
+#define STRING_Mn0 STR_M STR_n "\0"
+#define STRING_Modi0 STR_M STR_o STR_d STR_i "\0"
+#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
+#define STRING_Mro0 STR_M STR_r STR_o "\0"
+#define STRING_Multani0 STR_M STR_u STR_l STR_t STR_a STR_n STR_i "\0"
+#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
+#define STRING_N0 STR_N "\0"
+#define STRING_Nabataean0 STR_N STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0"
+#define STRING_Nd0 STR_N STR_d "\0"
+#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
+#define STRING_Nko0 STR_N STR_k STR_o "\0"
+#define STRING_Nl0 STR_N STR_l "\0"
+#define STRING_No0 STR_N STR_o "\0"
+#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
+#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
+#define STRING_Old_Hungarian0 STR_O STR_l STR_d STR_UNDERSCORE STR_H STR_u STR_n STR_g STR_a STR_r STR_i STR_a STR_n "\0"
+#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"
+#define STRING_Old_North_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_N STR_o STR_r STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
+#define STRING_Old_Permic0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_m STR_i STR_c "\0"
+#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"
+#define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
+#define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
+#define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
+#define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
+#define STRING_P0 STR_P "\0"
+#define STRING_Pahawh_Hmong0 STR_P STR_a STR_h STR_a STR_w STR_h STR_UNDERSCORE STR_H STR_m STR_o STR_n STR_g "\0"
+#define STRING_Palmyrene0 STR_P STR_a STR_l STR_m STR_y STR_r STR_e STR_n STR_e "\0"
+#define STRING_Pau_Cin_Hau0 STR_P STR_a STR_u STR_UNDERSCORE STR_C STR_i STR_n STR_UNDERSCORE STR_H STR_a STR_u "\0"
+#define STRING_Pc0 STR_P STR_c "\0"
+#define STRING_Pd0 STR_P STR_d "\0"
+#define STRING_Pe0 STR_P STR_e "\0"
+#define STRING_Pf0 STR_P STR_f "\0"
+#define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0"
+#define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"
+#define STRING_Pi0 STR_P STR_i "\0"
+#define STRING_Po0 STR_P STR_o "\0"
+#define STRING_Ps0 STR_P STR_s "\0"
+#define STRING_Psalter_Pahlavi0 STR_P STR_s STR_a STR_l STR_t STR_e STR_r STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
+#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"
+#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"
+#define STRING_S0 STR_S "\0"
+#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
+#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
+#define STRING_Sc0 STR_S STR_c "\0"
+#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0"
+#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
+#define STRING_Siddham0 STR_S STR_i STR_d STR_d STR_h STR_a STR_m "\0"
+#define STRING_SignWriting0 STR_S STR_i STR_g STR_n STR_W STR_r STR_i STR_t STR_i STR_n STR_g "\0"
+#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
+#define STRING_Sk0 STR_S STR_k "\0"
+#define STRING_Sm0 STR_S STR_m "\0"
+#define STRING_So0 STR_S STR_o "\0"
+#define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0"
+#define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
+#define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
+#define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0"
+#define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"
+#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"
+#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"
+#define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
+#define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0"
+#define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
+#define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
+#define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
+#define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
+#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"
+#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
+#define STRING_Tirhuta0 STR_T STR_i STR_r STR_h STR_u STR_t STR_a "\0"
+#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
+#define STRING_Vai0 STR_V STR_a STR_i "\0"
+#define STRING_Warang_Citi0 STR_W STR_a STR_r STR_a STR_n STR_g STR_UNDERSCORE STR_C STR_i STR_t STR_i "\0"
+#define STRING_Xan0 STR_X STR_a STR_n "\0"
+#define STRING_Xps0 STR_X STR_p STR_s "\0"
+#define STRING_Xsp0 STR_X STR_s STR_p "\0"
+#define STRING_Xuc0 STR_X STR_u STR_c "\0"
+#define STRING_Xwd0 STR_X STR_w STR_d "\0"
+#define STRING_Yi0 STR_Y STR_i "\0"
+#define STRING_Z0 STR_Z "\0"
+#define STRING_Zl0 STR_Z STR_l "\0"
+#define STRING_Zp0 STR_Z STR_p "\0"
+#define STRING_Zs0 STR_Z STR_s "\0"
+
+const char PRIV(utt_names)[] =
+ STRING_Ahom0
+ STRING_Anatolian_Hieroglyphs0
+ STRING_Any0
+ STRING_Arabic0
+ STRING_Armenian0
+ STRING_Avestan0
+ STRING_Balinese0
+ STRING_Bamum0
+ STRING_Bassa_Vah0
+ STRING_Batak0
+ STRING_Bengali0
+ STRING_Bopomofo0
+ STRING_Brahmi0
+ STRING_Braille0
+ STRING_Buginese0
+ STRING_Buhid0
+ STRING_C0
+ STRING_Canadian_Aboriginal0
+ STRING_Carian0
+ STRING_Caucasian_Albanian0
+ STRING_Cc0
+ STRING_Cf0
+ STRING_Chakma0
+ STRING_Cham0
+ STRING_Cherokee0
+ STRING_Cn0
+ STRING_Co0
+ STRING_Common0
+ STRING_Coptic0
+ STRING_Cs0
+ STRING_Cuneiform0
+ STRING_Cypriot0
+ STRING_Cyrillic0
+ STRING_Deseret0
+ STRING_Devanagari0
+ STRING_Duployan0
+ STRING_Egyptian_Hieroglyphs0
+ STRING_Elbasan0
+ STRING_Ethiopic0
+ STRING_Georgian0
+ STRING_Glagolitic0
+ STRING_Gothic0
+ STRING_Grantha0
+ STRING_Greek0
+ STRING_Gujarati0
+ STRING_Gurmukhi0
+ STRING_Han0
+ STRING_Hangul0
+ STRING_Hanunoo0
+ STRING_Hatran0
+ STRING_Hebrew0
+ STRING_Hiragana0
+ STRING_Imperial_Aramaic0
+ STRING_Inherited0
+ STRING_Inscriptional_Pahlavi0
+ STRING_Inscriptional_Parthian0
+ STRING_Javanese0
+ STRING_Kaithi0
+ STRING_Kannada0
+ STRING_Katakana0
+ STRING_Kayah_Li0
+ STRING_Kharoshthi0
+ STRING_Khmer0
+ STRING_Khojki0
+ STRING_Khudawadi0
+ STRING_L0
+ STRING_L_AMPERSAND0
+ STRING_Lao0
+ STRING_Latin0
+ STRING_Lepcha0
+ STRING_Limbu0
+ STRING_Linear_A0
+ STRING_Linear_B0
+ STRING_Lisu0
+ STRING_Ll0
+ STRING_Lm0
+ STRING_Lo0
+ STRING_Lt0
+ STRING_Lu0
+ STRING_Lycian0
+ STRING_Lydian0
+ STRING_M0
+ STRING_Mahajani0
+ STRING_Malayalam0
+ STRING_Mandaic0
+ STRING_Manichaean0
+ STRING_Mc0
+ STRING_Me0
+ STRING_Meetei_Mayek0
+ STRING_Mende_Kikakui0
+ STRING_Meroitic_Cursive0
+ STRING_Meroitic_Hieroglyphs0
+ STRING_Miao0
+ STRING_Mn0
+ STRING_Modi0
+ STRING_Mongolian0
+ STRING_Mro0
+ STRING_Multani0
+ STRING_Myanmar0
+ STRING_N0
+ STRING_Nabataean0
+ STRING_Nd0
+ STRING_New_Tai_Lue0
+ STRING_Nko0
+ STRING_Nl0
+ STRING_No0
+ STRING_Ogham0
+ STRING_Ol_Chiki0
+ STRING_Old_Hungarian0
+ STRING_Old_Italic0
+ STRING_Old_North_Arabian0
+ STRING_Old_Permic0
+ STRING_Old_Persian0
+ STRING_Old_South_Arabian0
+ STRING_Old_Turkic0
+ STRING_Oriya0
+ STRING_Osmanya0
+ STRING_P0
+ STRING_Pahawh_Hmong0
+ STRING_Palmyrene0
+ STRING_Pau_Cin_Hau0
+ STRING_Pc0
+ STRING_Pd0
+ STRING_Pe0
+ STRING_Pf0
+ STRING_Phags_Pa0
+ STRING_Phoenician0
+ STRING_Pi0
+ STRING_Po0
+ STRING_Ps0
+ STRING_Psalter_Pahlavi0
+ STRING_Rejang0
+ STRING_Runic0
+ STRING_S0
+ STRING_Samaritan0
+ STRING_Saurashtra0
+ STRING_Sc0
+ STRING_Sharada0
+ STRING_Shavian0
+ STRING_Siddham0
+ STRING_SignWriting0
+ STRING_Sinhala0
+ STRING_Sk0
+ STRING_Sm0
+ STRING_So0
+ STRING_Sora_Sompeng0
+ STRING_Sundanese0
+ STRING_Syloti_Nagri0
+ STRING_Syriac0
+ STRING_Tagalog0
+ STRING_Tagbanwa0
+ STRING_Tai_Le0
+ STRING_Tai_Tham0
+ STRING_Tai_Viet0
+ STRING_Takri0
+ STRING_Tamil0
+ STRING_Telugu0
+ STRING_Thaana0
+ STRING_Thai0
+ STRING_Tibetan0
+ STRING_Tifinagh0
+ STRING_Tirhuta0
+ STRING_Ugaritic0
+ STRING_Vai0
+ STRING_Warang_Citi0
+ STRING_Xan0
+ STRING_Xps0
+ STRING_Xsp0
+ STRING_Xuc0
+ STRING_Xwd0
+ STRING_Yi0
+ STRING_Z0
+ STRING_Zl0
+ STRING_Zp0
+ STRING_Zs0;
+
+const ucp_type_table PRIV(utt)[] = {
+ { 0, PT_SC, ucp_Ahom },
+ { 5, PT_SC, ucp_Anatolian_Hieroglyphs },
+ { 27, PT_ANY, 0 },
+ { 31, PT_SC, ucp_Arabic },
+ { 38, PT_SC, ucp_Armenian },
+ { 47, PT_SC, ucp_Avestan },
+ { 55, PT_SC, ucp_Balinese },
+ { 64, PT_SC, ucp_Bamum },
+ { 70, PT_SC, ucp_Bassa_Vah },
+ { 80, PT_SC, ucp_Batak },
+ { 86, PT_SC, ucp_Bengali },
+ { 94, PT_SC, ucp_Bopomofo },
+ { 103, PT_SC, ucp_Brahmi },
+ { 110, PT_SC, ucp_Braille },
+ { 118, PT_SC, ucp_Buginese },
+ { 127, PT_SC, ucp_Buhid },
+ { 133, PT_GC, ucp_C },
+ { 135, PT_SC, ucp_Canadian_Aboriginal },
+ { 155, PT_SC, ucp_Carian },
+ { 162, PT_SC, ucp_Caucasian_Albanian },
+ { 181, PT_PC, ucp_Cc },
+ { 184, PT_PC, ucp_Cf },
+ { 187, PT_SC, ucp_Chakma },
+ { 194, PT_SC, ucp_Cham },
+ { 199, PT_SC, ucp_Cherokee },
+ { 208, PT_PC, ucp_Cn },
+ { 211, PT_PC, ucp_Co },
+ { 214, PT_SC, ucp_Common },
+ { 221, PT_SC, ucp_Coptic },
+ { 228, PT_PC, ucp_Cs },
+ { 231, PT_SC, ucp_Cuneiform },
+ { 241, PT_SC, ucp_Cypriot },
+ { 249, PT_SC, ucp_Cyrillic },
+ { 258, PT_SC, ucp_Deseret },
+ { 266, PT_SC, ucp_Devanagari },
+ { 277, PT_SC, ucp_Duployan },
+ { 286, PT_SC, ucp_Egyptian_Hieroglyphs },
+ { 307, PT_SC, ucp_Elbasan },
+ { 315, PT_SC, ucp_Ethiopic },
+ { 324, PT_SC, ucp_Georgian },
+ { 333, PT_SC, ucp_Glagolitic },
+ { 344, PT_SC, ucp_Gothic },
+ { 351, PT_SC, ucp_Grantha },
+ { 359, PT_SC, ucp_Greek },
+ { 365, PT_SC, ucp_Gujarati },
+ { 374, PT_SC, ucp_Gurmukhi },
+ { 383, PT_SC, ucp_Han },
+ { 387, PT_SC, ucp_Hangul },
+ { 394, PT_SC, ucp_Hanunoo },
+ { 402, PT_SC, ucp_Hatran },
+ { 409, PT_SC, ucp_Hebrew },
+ { 416, PT_SC, ucp_Hiragana },
+ { 425, PT_SC, ucp_Imperial_Aramaic },
+ { 442, PT_SC, ucp_Inherited },
+ { 452, PT_SC, ucp_Inscriptional_Pahlavi },
+ { 474, PT_SC, ucp_Inscriptional_Parthian },
+ { 497, PT_SC, ucp_Javanese },
+ { 506, PT_SC, ucp_Kaithi },
+ { 513, PT_SC, ucp_Kannada },
+ { 521, PT_SC, ucp_Katakana },
+ { 530, PT_SC, ucp_Kayah_Li },
+ { 539, PT_SC, ucp_Kharoshthi },
+ { 550, PT_SC, ucp_Khmer },
+ { 556, PT_SC, ucp_Khojki },
+ { 563, PT_SC, ucp_Khudawadi },
+ { 573, PT_GC, ucp_L },
+ { 575, PT_LAMP, 0 },
+ { 578, PT_SC, ucp_Lao },
+ { 582, PT_SC, ucp_Latin },
+ { 588, PT_SC, ucp_Lepcha },
+ { 595, PT_SC, ucp_Limbu },
+ { 601, PT_SC, ucp_Linear_A },
+ { 610, PT_SC, ucp_Linear_B },
+ { 619, PT_SC, ucp_Lisu },
+ { 624, PT_PC, ucp_Ll },
+ { 627, PT_PC, ucp_Lm },
+ { 630, PT_PC, ucp_Lo },
+ { 633, PT_PC, ucp_Lt },
+ { 636, PT_PC, ucp_Lu },
+ { 639, PT_SC, ucp_Lycian },
+ { 646, PT_SC, ucp_Lydian },
+ { 653, PT_GC, ucp_M },
+ { 655, PT_SC, ucp_Mahajani },
+ { 664, PT_SC, ucp_Malayalam },
+ { 674, PT_SC, ucp_Mandaic },
+ { 682, PT_SC, ucp_Manichaean },
+ { 693, PT_PC, ucp_Mc },
+ { 696, PT_PC, ucp_Me },
+ { 699, PT_SC, ucp_Meetei_Mayek },
+ { 712, PT_SC, ucp_Mende_Kikakui },
+ { 726, PT_SC, ucp_Meroitic_Cursive },
+ { 743, PT_SC, ucp_Meroitic_Hieroglyphs },
+ { 764, PT_SC, ucp_Miao },
+ { 769, PT_PC, ucp_Mn },
+ { 772, PT_SC, ucp_Modi },
+ { 777, PT_SC, ucp_Mongolian },
+ { 787, PT_SC, ucp_Mro },
+ { 791, PT_SC, ucp_Multani },
+ { 799, PT_SC, ucp_Myanmar },
+ { 807, PT_GC, ucp_N },
+ { 809, PT_SC, ucp_Nabataean },
+ { 819, PT_PC, ucp_Nd },
+ { 822, PT_SC, ucp_New_Tai_Lue },
+ { 834, PT_SC, ucp_Nko },
+ { 838, PT_PC, ucp_Nl },
+ { 841, PT_PC, ucp_No },
+ { 844, PT_SC, ucp_Ogham },
+ { 850, PT_SC, ucp_Ol_Chiki },
+ { 859, PT_SC, ucp_Old_Hungarian },
+ { 873, PT_SC, ucp_Old_Italic },
+ { 884, PT_SC, ucp_Old_North_Arabian },
+ { 902, PT_SC, ucp_Old_Permic },
+ { 913, PT_SC, ucp_Old_Persian },
+ { 925, PT_SC, ucp_Old_South_Arabian },
+ { 943, PT_SC, ucp_Old_Turkic },
+ { 954, PT_SC, ucp_Oriya },
+ { 960, PT_SC, ucp_Osmanya },
+ { 968, PT_GC, ucp_P },
+ { 970, PT_SC, ucp_Pahawh_Hmong },
+ { 983, PT_SC, ucp_Palmyrene },
+ { 993, PT_SC, ucp_Pau_Cin_Hau },
+ { 1005, PT_PC, ucp_Pc },
+ { 1008, PT_PC, ucp_Pd },
+ { 1011, PT_PC, ucp_Pe },
+ { 1014, PT_PC, ucp_Pf },
+ { 1017, PT_SC, ucp_Phags_Pa },
+ { 1026, PT_SC, ucp_Phoenician },
+ { 1037, PT_PC, ucp_Pi },
+ { 1040, PT_PC, ucp_Po },
+ { 1043, PT_PC, ucp_Ps },
+ { 1046, PT_SC, ucp_Psalter_Pahlavi },
+ { 1062, PT_SC, ucp_Rejang },
+ { 1069, PT_SC, ucp_Runic },
+ { 1075, PT_GC, ucp_S },
+ { 1077, PT_SC, ucp_Samaritan },
+ { 1087, PT_SC, ucp_Saurashtra },
+ { 1098, PT_PC, ucp_Sc },
+ { 1101, PT_SC, ucp_Sharada },
+ { 1109, PT_SC, ucp_Shavian },
+ { 1117, PT_SC, ucp_Siddham },
+ { 1125, PT_SC, ucp_SignWriting },
+ { 1137, PT_SC, ucp_Sinhala },
+ { 1145, PT_PC, ucp_Sk },
+ { 1148, PT_PC, ucp_Sm },
+ { 1151, PT_PC, ucp_So },
+ { 1154, PT_SC, ucp_Sora_Sompeng },
+ { 1167, PT_SC, ucp_Sundanese },
+ { 1177, PT_SC, ucp_Syloti_Nagri },
+ { 1190, PT_SC, ucp_Syriac },
+ { 1197, PT_SC, ucp_Tagalog },
+ { 1205, PT_SC, ucp_Tagbanwa },
+ { 1214, PT_SC, ucp_Tai_Le },
+ { 1221, PT_SC, ucp_Tai_Tham },
+ { 1230, PT_SC, ucp_Tai_Viet },
+ { 1239, PT_SC, ucp_Takri },
+ { 1245, PT_SC, ucp_Tamil },
+ { 1251, PT_SC, ucp_Telugu },
+ { 1258, PT_SC, ucp_Thaana },
+ { 1265, PT_SC, ucp_Thai },
+ { 1270, PT_SC, ucp_Tibetan },
+ { 1278, PT_SC, ucp_Tifinagh },
+ { 1287, PT_SC, ucp_Tirhuta },
+ { 1295, PT_SC, ucp_Ugaritic },
+ { 1304, PT_SC, ucp_Vai },
+ { 1308, PT_SC, ucp_Warang_Citi },
+ { 1320, PT_ALNUM, 0 },
+ { 1324, PT_PXSPACE, 0 },
+ { 1328, PT_SPACE, 0 },
+ { 1332, PT_UCNC, 0 },
+ { 1336, PT_WORD, 0 },
+ { 1340, PT_SC, ucp_Yi },
+ { 1343, PT_GC, ucp_Z },
+ { 1345, PT_PC, ucp_Zl },
+ { 1348, PT_PC, ucp_Zp },
+ { 1351, PT_PC, ucp_Zs }
+};
+
+const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
+
+#endif /* SUPPORT_UNICODE */
+
+/* End of pcre2_tables.c */
diff --git a/thirdparty/pcre2/src/pcre2_ucd.c b/thirdparty/pcre2/src/pcre2_ucd.c
new file mode 100644
index 0000000000..116f537b38
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_ucd.c
@@ -0,0 +1,3747 @@
+/* This module is generated by the maint/MultiStage2.py script.
+Do not modify it by hand. Instead modify the script and run it
+to regenerate this code.
+
+As well as being part of the PCRE2 library, this module is #included
+by the pcre2test program, which redefines the PRIV macro to change
+table names from _pcre2_xxx to xxxx, thereby avoiding name clashes
+with the library. At present, just one of these tables is actually
+needed. */
+
+#ifndef PCRE2_PCRE2TEST
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre2_internal.h"
+
+#endif /* PCRE2_PCRE2TEST */
+
+/* Unicode character database. */
+/* This file was autogenerated by the MultiStage2.py script. */
+/* Total size: 75072 bytes, block size: 128. */
+
+/* The tables herein are needed only when UCP support is built,
+and in PCRE2 that happens automatically with UTF support.
+This module should not be referenced otherwise, so
+it should not matter whether it is compiled or not. However
+a comment was received about space saving - maybe the guy linked
+all the modules rather than using a library - so we include a
+condition to cut out the tables when not needed. But don't leave
+a totally empty module because some compilers barf at that.
+Instead, just supply small dummy tables. */
+
+#ifndef SUPPORT_UNICODE
+const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0 }};
+const uint8_t PRIV(ucd_stage1)[] = {0};
+const uint16_t PRIV(ucd_stage2)[] = {0};
+const uint32_t PRIV(ucd_caseless_sets)[] = {0};
+#else
+
+const char *PRIV(unicode_version) = "8.0.0";
+
+/* When recompiling tables with a new Unicode version, please check the
+types in this structure definition from pcre2_internal.h (the actual
+field names will be different):
+
+typedef struct {
+uint8_t property_0;
+uint8_t property_1;
+uint8_t property_2;
+uint8_t property_3;
+pcre_int32 property_4;
+} ucd_record;
+*/
+
+
+const uint32_t PRIV(ucd_caseless_sets)[] = {
+ NOTACHAR,
+ 0x0053, 0x0073, 0x017f, NOTACHAR,
+ 0x01c4, 0x01c5, 0x01c6, NOTACHAR,
+ 0x01c7, 0x01c8, 0x01c9, NOTACHAR,
+ 0x01ca, 0x01cb, 0x01cc, NOTACHAR,
+ 0x01f1, 0x01f2, 0x01f3, NOTACHAR,
+ 0x0345, 0x0399, 0x03b9, 0x1fbe, NOTACHAR,
+ 0x00b5, 0x039c, 0x03bc, NOTACHAR,
+ 0x03a3, 0x03c2, 0x03c3, NOTACHAR,
+ 0x0392, 0x03b2, 0x03d0, NOTACHAR,
+ 0x0398, 0x03b8, 0x03d1, 0x03f4, NOTACHAR,
+ 0x03a6, 0x03c6, 0x03d5, NOTACHAR,
+ 0x03a0, 0x03c0, 0x03d6, NOTACHAR,
+ 0x039a, 0x03ba, 0x03f0, NOTACHAR,
+ 0x03a1, 0x03c1, 0x03f1, NOTACHAR,
+ 0x0395, 0x03b5, 0x03f5, NOTACHAR,
+ 0x1e60, 0x1e61, 0x1e9b, NOTACHAR,
+ 0x03a9, 0x03c9, 0x2126, NOTACHAR,
+ 0x004b, 0x006b, 0x212a, NOTACHAR,
+ 0x00c5, 0x00e5, 0x212b, NOTACHAR,
+};
+
+/* When #included in pcre2test, we don't need this large table. */
+
+#ifndef PCRE2_PCRE2TEST
+
+const ucd_record PRIV(ucd_records)[] = { /* 5952 bytes, record size 8 */
+ { 9, 0, 2, 0, 0, }, /* 0 */
+ { 9, 0, 1, 0, 0, }, /* 1 */
+ { 9, 0, 0, 0, 0, }, /* 2 */
+ { 9, 29, 12, 0, 0, }, /* 3 */
+ { 9, 21, 12, 0, 0, }, /* 4 */
+ { 9, 23, 12, 0, 0, }, /* 5 */
+ { 9, 22, 12, 0, 0, }, /* 6 */
+ { 9, 18, 12, 0, 0, }, /* 7 */
+ { 9, 25, 12, 0, 0, }, /* 8 */
+ { 9, 17, 12, 0, 0, }, /* 9 */
+ { 9, 13, 12, 0, 0, }, /* 10 */
+ { 33, 9, 12, 0, 32, }, /* 11 */
+ { 33, 9, 12, 71, 32, }, /* 12 */
+ { 33, 9, 12, 1, 32, }, /* 13 */
+ { 9, 24, 12, 0, 0, }, /* 14 */
+ { 9, 16, 12, 0, 0, }, /* 15 */
+ { 33, 5, 12, 0, -32, }, /* 16 */
+ { 33, 5, 12, 71, -32, }, /* 17 */
+ { 33, 5, 12, 1, -32, }, /* 18 */
+ { 9, 26, 12, 0, 0, }, /* 19 */
+ { 33, 7, 12, 0, 0, }, /* 20 */
+ { 9, 20, 12, 0, 0, }, /* 21 */
+ { 9, 1, 2, 0, 0, }, /* 22 */
+ { 9, 15, 12, 0, 0, }, /* 23 */
+ { 9, 5, 12, 26, 775, }, /* 24 */
+ { 9, 19, 12, 0, 0, }, /* 25 */
+ { 33, 9, 12, 75, 32, }, /* 26 */
+ { 33, 5, 12, 0, 7615, }, /* 27 */
+ { 33, 5, 12, 75, -32, }, /* 28 */
+ { 33, 5, 12, 0, 121, }, /* 29 */
+ { 33, 9, 12, 0, 1, }, /* 30 */
+ { 33, 5, 12, 0, -1, }, /* 31 */
+ { 33, 9, 12, 0, 0, }, /* 32 */
+ { 33, 5, 12, 0, 0, }, /* 33 */
+ { 33, 9, 12, 0, -121, }, /* 34 */
+ { 33, 5, 12, 1, -268, }, /* 35 */
+ { 33, 5, 12, 0, 195, }, /* 36 */
+ { 33, 9, 12, 0, 210, }, /* 37 */
+ { 33, 9, 12, 0, 206, }, /* 38 */
+ { 33, 9, 12, 0, 205, }, /* 39 */
+ { 33, 9, 12, 0, 79, }, /* 40 */
+ { 33, 9, 12, 0, 202, }, /* 41 */
+ { 33, 9, 12, 0, 203, }, /* 42 */
+ { 33, 9, 12, 0, 207, }, /* 43 */
+ { 33, 5, 12, 0, 97, }, /* 44 */
+ { 33, 9, 12, 0, 211, }, /* 45 */
+ { 33, 9, 12, 0, 209, }, /* 46 */
+ { 33, 5, 12, 0, 163, }, /* 47 */
+ { 33, 9, 12, 0, 213, }, /* 48 */
+ { 33, 5, 12, 0, 130, }, /* 49 */
+ { 33, 9, 12, 0, 214, }, /* 50 */
+ { 33, 9, 12, 0, 218, }, /* 51 */
+ { 33, 9, 12, 0, 217, }, /* 52 */
+ { 33, 9, 12, 0, 219, }, /* 53 */
+ { 33, 5, 12, 0, 56, }, /* 54 */
+ { 33, 9, 12, 5, 2, }, /* 55 */
+ { 33, 8, 12, 5, 1, }, /* 56 */
+ { 33, 5, 12, 5, -2, }, /* 57 */
+ { 33, 9, 12, 9, 2, }, /* 58 */
+ { 33, 8, 12, 9, 1, }, /* 59 */
+ { 33, 5, 12, 9, -2, }, /* 60 */
+ { 33, 9, 12, 13, 2, }, /* 61 */
+ { 33, 8, 12, 13, 1, }, /* 62 */
+ { 33, 5, 12, 13, -2, }, /* 63 */
+ { 33, 5, 12, 0, -79, }, /* 64 */
+ { 33, 9, 12, 17, 2, }, /* 65 */
+ { 33, 8, 12, 17, 1, }, /* 66 */
+ { 33, 5, 12, 17, -2, }, /* 67 */
+ { 33, 9, 12, 0, -97, }, /* 68 */
+ { 33, 9, 12, 0, -56, }, /* 69 */
+ { 33, 9, 12, 0, -130, }, /* 70 */
+ { 33, 9, 12, 0, 10795, }, /* 71 */
+ { 33, 9, 12, 0, -163, }, /* 72 */
+ { 33, 9, 12, 0, 10792, }, /* 73 */
+ { 33, 5, 12, 0, 10815, }, /* 74 */
+ { 33, 9, 12, 0, -195, }, /* 75 */
+ { 33, 9, 12, 0, 69, }, /* 76 */
+ { 33, 9, 12, 0, 71, }, /* 77 */
+ { 33, 5, 12, 0, 10783, }, /* 78 */
+ { 33, 5, 12, 0, 10780, }, /* 79 */
+ { 33, 5, 12, 0, 10782, }, /* 80 */
+ { 33, 5, 12, 0, -210, }, /* 81 */
+ { 33, 5, 12, 0, -206, }, /* 82 */
+ { 33, 5, 12, 0, -205, }, /* 83 */
+ { 33, 5, 12, 0, -202, }, /* 84 */
+ { 33, 5, 12, 0, -203, }, /* 85 */
+ { 33, 5, 12, 0, 42319, }, /* 86 */
+ { 33, 5, 12, 0, 42315, }, /* 87 */
+ { 33, 5, 12, 0, -207, }, /* 88 */
+ { 33, 5, 12, 0, 42280, }, /* 89 */
+ { 33, 5, 12, 0, 42308, }, /* 90 */
+ { 33, 5, 12, 0, -209, }, /* 91 */
+ { 33, 5, 12, 0, -211, }, /* 92 */
+ { 33, 5, 12, 0, 10743, }, /* 93 */
+ { 33, 5, 12, 0, 42305, }, /* 94 */
+ { 33, 5, 12, 0, 10749, }, /* 95 */
+ { 33, 5, 12, 0, -213, }, /* 96 */
+ { 33, 5, 12, 0, -214, }, /* 97 */
+ { 33, 5, 12, 0, 10727, }, /* 98 */
+ { 33, 5, 12, 0, -218, }, /* 99 */
+ { 33, 5, 12, 0, 42282, }, /* 100 */
+ { 33, 5, 12, 0, -69, }, /* 101 */
+ { 33, 5, 12, 0, -217, }, /* 102 */
+ { 33, 5, 12, 0, -71, }, /* 103 */
+ { 33, 5, 12, 0, -219, }, /* 104 */
+ { 33, 5, 12, 0, 42261, }, /* 105 */
+ { 33, 5, 12, 0, 42258, }, /* 106 */
+ { 33, 6, 12, 0, 0, }, /* 107 */
+ { 9, 6, 12, 0, 0, }, /* 108 */
+ { 3, 24, 12, 0, 0, }, /* 109 */
+ { 27, 12, 3, 0, 0, }, /* 110 */
+ { 27, 12, 3, 21, 116, }, /* 111 */
+ { 19, 9, 12, 0, 1, }, /* 112 */
+ { 19, 5, 12, 0, -1, }, /* 113 */
+ { 19, 24, 12, 0, 0, }, /* 114 */
+ { 9, 2, 12, 0, 0, }, /* 115 */
+ { 19, 6, 12, 0, 0, }, /* 116 */
+ { 19, 5, 12, 0, 130, }, /* 117 */
+ { 19, 9, 12, 0, 116, }, /* 118 */
+ { 19, 9, 12, 0, 38, }, /* 119 */
+ { 19, 9, 12, 0, 37, }, /* 120 */
+ { 19, 9, 12, 0, 64, }, /* 121 */
+ { 19, 9, 12, 0, 63, }, /* 122 */
+ { 19, 5, 12, 0, 0, }, /* 123 */
+ { 19, 9, 12, 0, 32, }, /* 124 */
+ { 19, 9, 12, 34, 32, }, /* 125 */
+ { 19, 9, 12, 59, 32, }, /* 126 */
+ { 19, 9, 12, 38, 32, }, /* 127 */
+ { 19, 9, 12, 21, 32, }, /* 128 */
+ { 19, 9, 12, 51, 32, }, /* 129 */
+ { 19, 9, 12, 26, 32, }, /* 130 */
+ { 19, 9, 12, 47, 32, }, /* 131 */
+ { 19, 9, 12, 55, 32, }, /* 132 */
+ { 19, 9, 12, 30, 32, }, /* 133 */
+ { 19, 9, 12, 43, 32, }, /* 134 */
+ { 19, 9, 12, 67, 32, }, /* 135 */
+ { 19, 5, 12, 0, -38, }, /* 136 */
+ { 19, 5, 12, 0, -37, }, /* 137 */
+ { 19, 5, 12, 0, -32, }, /* 138 */
+ { 19, 5, 12, 34, -32, }, /* 139 */
+ { 19, 5, 12, 59, -32, }, /* 140 */
+ { 19, 5, 12, 38, -32, }, /* 141 */
+ { 19, 5, 12, 21, -116, }, /* 142 */
+ { 19, 5, 12, 51, -32, }, /* 143 */
+ { 19, 5, 12, 26, -775, }, /* 144 */
+ { 19, 5, 12, 47, -32, }, /* 145 */
+ { 19, 5, 12, 55, -32, }, /* 146 */
+ { 19, 5, 12, 30, 1, }, /* 147 */
+ { 19, 5, 12, 30, -32, }, /* 148 */
+ { 19, 5, 12, 43, -32, }, /* 149 */
+ { 19, 5, 12, 67, -32, }, /* 150 */
+ { 19, 5, 12, 0, -64, }, /* 151 */
+ { 19, 5, 12, 0, -63, }, /* 152 */
+ { 19, 9, 12, 0, 8, }, /* 153 */
+ { 19, 5, 12, 34, -30, }, /* 154 */
+ { 19, 5, 12, 38, -25, }, /* 155 */
+ { 19, 9, 12, 0, 0, }, /* 156 */
+ { 19, 5, 12, 43, -15, }, /* 157 */
+ { 19, 5, 12, 47, -22, }, /* 158 */
+ { 19, 5, 12, 0, -8, }, /* 159 */
+ { 10, 9, 12, 0, 1, }, /* 160 */
+ { 10, 5, 12, 0, -1, }, /* 161 */
+ { 19, 5, 12, 51, -54, }, /* 162 */
+ { 19, 5, 12, 55, -48, }, /* 163 */
+ { 19, 5, 12, 0, 7, }, /* 164 */
+ { 19, 5, 12, 0, -116, }, /* 165 */
+ { 19, 9, 12, 38, -60, }, /* 166 */
+ { 19, 5, 12, 59, -64, }, /* 167 */
+ { 19, 25, 12, 0, 0, }, /* 168 */
+ { 19, 9, 12, 0, -7, }, /* 169 */
+ { 19, 9, 12, 0, -130, }, /* 170 */
+ { 12, 9, 12, 0, 80, }, /* 171 */
+ { 12, 9, 12, 0, 32, }, /* 172 */
+ { 12, 5, 12, 0, -32, }, /* 173 */
+ { 12, 5, 12, 0, -80, }, /* 174 */
+ { 12, 9, 12, 0, 1, }, /* 175 */
+ { 12, 5, 12, 0, -1, }, /* 176 */
+ { 12, 26, 12, 0, 0, }, /* 177 */
+ { 12, 12, 3, 0, 0, }, /* 178 */
+ { 12, 11, 3, 0, 0, }, /* 179 */
+ { 12, 9, 12, 0, 15, }, /* 180 */
+ { 12, 5, 12, 0, -15, }, /* 181 */
+ { 1, 9, 12, 0, 48, }, /* 182 */
+ { 1, 6, 12, 0, 0, }, /* 183 */
+ { 1, 21, 12, 0, 0, }, /* 184 */
+ { 1, 5, 12, 0, -48, }, /* 185 */
+ { 1, 5, 12, 0, 0, }, /* 186 */
+ { 1, 17, 12, 0, 0, }, /* 187 */
+ { 1, 26, 12, 0, 0, }, /* 188 */
+ { 1, 23, 12, 0, 0, }, /* 189 */
+ { 25, 12, 3, 0, 0, }, /* 190 */
+ { 25, 17, 12, 0, 0, }, /* 191 */
+ { 25, 21, 12, 0, 0, }, /* 192 */
+ { 25, 7, 12, 0, 0, }, /* 193 */
+ { 0, 1, 2, 0, 0, }, /* 194 */
+ { 0, 25, 12, 0, 0, }, /* 195 */
+ { 0, 21, 12, 0, 0, }, /* 196 */
+ { 0, 23, 12, 0, 0, }, /* 197 */
+ { 0, 26, 12, 0, 0, }, /* 198 */
+ { 0, 12, 3, 0, 0, }, /* 199 */
+ { 0, 7, 12, 0, 0, }, /* 200 */
+ { 0, 13, 12, 0, 0, }, /* 201 */
+ { 0, 6, 12, 0, 0, }, /* 202 */
+ { 49, 21, 12, 0, 0, }, /* 203 */
+ { 49, 1, 2, 0, 0, }, /* 204 */
+ { 49, 7, 12, 0, 0, }, /* 205 */
+ { 49, 12, 3, 0, 0, }, /* 206 */
+ { 55, 7, 12, 0, 0, }, /* 207 */
+ { 55, 12, 3, 0, 0, }, /* 208 */
+ { 63, 13, 12, 0, 0, }, /* 209 */
+ { 63, 7, 12, 0, 0, }, /* 210 */
+ { 63, 12, 3, 0, 0, }, /* 211 */
+ { 63, 6, 12, 0, 0, }, /* 212 */
+ { 63, 26, 12, 0, 0, }, /* 213 */
+ { 63, 21, 12, 0, 0, }, /* 214 */
+ { 89, 7, 12, 0, 0, }, /* 215 */
+ { 89, 12, 3, 0, 0, }, /* 216 */
+ { 89, 6, 12, 0, 0, }, /* 217 */
+ { 89, 21, 12, 0, 0, }, /* 218 */
+ { 94, 7, 12, 0, 0, }, /* 219 */
+ { 94, 12, 3, 0, 0, }, /* 220 */
+ { 94, 21, 12, 0, 0, }, /* 221 */
+ { 14, 12, 3, 0, 0, }, /* 222 */
+ { 14, 10, 5, 0, 0, }, /* 223 */
+ { 14, 7, 12, 0, 0, }, /* 224 */
+ { 14, 13, 12, 0, 0, }, /* 225 */
+ { 14, 21, 12, 0, 0, }, /* 226 */
+ { 14, 6, 12, 0, 0, }, /* 227 */
+ { 2, 7, 12, 0, 0, }, /* 228 */
+ { 2, 12, 3, 0, 0, }, /* 229 */
+ { 2, 10, 5, 0, 0, }, /* 230 */
+ { 2, 10, 3, 0, 0, }, /* 231 */
+ { 2, 13, 12, 0, 0, }, /* 232 */
+ { 2, 23, 12, 0, 0, }, /* 233 */
+ { 2, 15, 12, 0, 0, }, /* 234 */
+ { 2, 26, 12, 0, 0, }, /* 235 */
+ { 21, 12, 3, 0, 0, }, /* 236 */
+ { 21, 10, 5, 0, 0, }, /* 237 */
+ { 21, 7, 12, 0, 0, }, /* 238 */
+ { 21, 13, 12, 0, 0, }, /* 239 */
+ { 20, 12, 3, 0, 0, }, /* 240 */
+ { 20, 10, 5, 0, 0, }, /* 241 */
+ { 20, 7, 12, 0, 0, }, /* 242 */
+ { 20, 13, 12, 0, 0, }, /* 243 */
+ { 20, 21, 12, 0, 0, }, /* 244 */
+ { 20, 23, 12, 0, 0, }, /* 245 */
+ { 43, 12, 3, 0, 0, }, /* 246 */
+ { 43, 10, 5, 0, 0, }, /* 247 */
+ { 43, 7, 12, 0, 0, }, /* 248 */
+ { 43, 10, 3, 0, 0, }, /* 249 */
+ { 43, 13, 12, 0, 0, }, /* 250 */
+ { 43, 26, 12, 0, 0, }, /* 251 */
+ { 43, 15, 12, 0, 0, }, /* 252 */
+ { 53, 12, 3, 0, 0, }, /* 253 */
+ { 53, 7, 12, 0, 0, }, /* 254 */
+ { 53, 10, 3, 0, 0, }, /* 255 */
+ { 53, 10, 5, 0, 0, }, /* 256 */
+ { 53, 13, 12, 0, 0, }, /* 257 */
+ { 53, 15, 12, 0, 0, }, /* 258 */
+ { 53, 26, 12, 0, 0, }, /* 259 */
+ { 53, 23, 12, 0, 0, }, /* 260 */
+ { 54, 12, 3, 0, 0, }, /* 261 */
+ { 54, 10, 5, 0, 0, }, /* 262 */
+ { 54, 7, 12, 0, 0, }, /* 263 */
+ { 54, 13, 12, 0, 0, }, /* 264 */
+ { 54, 15, 12, 0, 0, }, /* 265 */
+ { 54, 26, 12, 0, 0, }, /* 266 */
+ { 28, 12, 3, 0, 0, }, /* 267 */
+ { 28, 10, 5, 0, 0, }, /* 268 */
+ { 28, 7, 12, 0, 0, }, /* 269 */
+ { 28, 10, 3, 0, 0, }, /* 270 */
+ { 28, 13, 12, 0, 0, }, /* 271 */
+ { 36, 12, 3, 0, 0, }, /* 272 */
+ { 36, 10, 5, 0, 0, }, /* 273 */
+ { 36, 7, 12, 0, 0, }, /* 274 */
+ { 36, 10, 3, 0, 0, }, /* 275 */
+ { 36, 13, 12, 0, 0, }, /* 276 */
+ { 36, 15, 12, 0, 0, }, /* 277 */
+ { 36, 26, 12, 0, 0, }, /* 278 */
+ { 47, 10, 5, 0, 0, }, /* 279 */
+ { 47, 7, 12, 0, 0, }, /* 280 */
+ { 47, 12, 3, 0, 0, }, /* 281 */
+ { 47, 10, 3, 0, 0, }, /* 282 */
+ { 47, 13, 12, 0, 0, }, /* 283 */
+ { 47, 21, 12, 0, 0, }, /* 284 */
+ { 56, 7, 12, 0, 0, }, /* 285 */
+ { 56, 12, 3, 0, 0, }, /* 286 */
+ { 56, 7, 5, 0, 0, }, /* 287 */
+ { 56, 6, 12, 0, 0, }, /* 288 */
+ { 56, 21, 12, 0, 0, }, /* 289 */
+ { 56, 13, 12, 0, 0, }, /* 290 */
+ { 32, 7, 12, 0, 0, }, /* 291 */
+ { 32, 12, 3, 0, 0, }, /* 292 */
+ { 32, 7, 5, 0, 0, }, /* 293 */
+ { 32, 6, 12, 0, 0, }, /* 294 */
+ { 32, 13, 12, 0, 0, }, /* 295 */
+ { 57, 7, 12, 0, 0, }, /* 296 */
+ { 57, 26, 12, 0, 0, }, /* 297 */
+ { 57, 21, 12, 0, 0, }, /* 298 */
+ { 57, 12, 3, 0, 0, }, /* 299 */
+ { 57, 13, 12, 0, 0, }, /* 300 */
+ { 57, 15, 12, 0, 0, }, /* 301 */
+ { 57, 22, 12, 0, 0, }, /* 302 */
+ { 57, 18, 12, 0, 0, }, /* 303 */
+ { 57, 10, 5, 0, 0, }, /* 304 */
+ { 38, 7, 12, 0, 0, }, /* 305 */
+ { 38, 10, 12, 0, 0, }, /* 306 */
+ { 38, 12, 3, 0, 0, }, /* 307 */
+ { 38, 10, 5, 0, 0, }, /* 308 */
+ { 38, 13, 12, 0, 0, }, /* 309 */
+ { 38, 21, 12, 0, 0, }, /* 310 */
+ { 38, 26, 12, 0, 0, }, /* 311 */
+ { 16, 9, 12, 0, 7264, }, /* 312 */
+ { 16, 7, 12, 0, 0, }, /* 313 */
+ { 16, 6, 12, 0, 0, }, /* 314 */
+ { 23, 7, 6, 0, 0, }, /* 315 */
+ { 23, 7, 7, 0, 0, }, /* 316 */
+ { 23, 7, 8, 0, 0, }, /* 317 */
+ { 15, 7, 12, 0, 0, }, /* 318 */
+ { 15, 12, 3, 0, 0, }, /* 319 */
+ { 15, 21, 12, 0, 0, }, /* 320 */
+ { 15, 15, 12, 0, 0, }, /* 321 */
+ { 15, 26, 12, 0, 0, }, /* 322 */
+ { 8, 9, 12, 0, 38864, }, /* 323 */
+ { 8, 9, 12, 0, 8, }, /* 324 */
+ { 8, 5, 12, 0, -8, }, /* 325 */
+ { 7, 17, 12, 0, 0, }, /* 326 */
+ { 7, 7, 12, 0, 0, }, /* 327 */
+ { 7, 21, 12, 0, 0, }, /* 328 */
+ { 40, 29, 12, 0, 0, }, /* 329 */
+ { 40, 7, 12, 0, 0, }, /* 330 */
+ { 40, 22, 12, 0, 0, }, /* 331 */
+ { 40, 18, 12, 0, 0, }, /* 332 */
+ { 45, 7, 12, 0, 0, }, /* 333 */
+ { 45, 14, 12, 0, 0, }, /* 334 */
+ { 50, 7, 12, 0, 0, }, /* 335 */
+ { 50, 12, 3, 0, 0, }, /* 336 */
+ { 24, 7, 12, 0, 0, }, /* 337 */
+ { 24, 12, 3, 0, 0, }, /* 338 */
+ { 6, 7, 12, 0, 0, }, /* 339 */
+ { 6, 12, 3, 0, 0, }, /* 340 */
+ { 51, 7, 12, 0, 0, }, /* 341 */
+ { 51, 12, 3, 0, 0, }, /* 342 */
+ { 31, 7, 12, 0, 0, }, /* 343 */
+ { 31, 12, 3, 0, 0, }, /* 344 */
+ { 31, 10, 5, 0, 0, }, /* 345 */
+ { 31, 21, 12, 0, 0, }, /* 346 */
+ { 31, 6, 12, 0, 0, }, /* 347 */
+ { 31, 23, 12, 0, 0, }, /* 348 */
+ { 31, 13, 12, 0, 0, }, /* 349 */
+ { 31, 15, 12, 0, 0, }, /* 350 */
+ { 37, 21, 12, 0, 0, }, /* 351 */
+ { 37, 17, 12, 0, 0, }, /* 352 */
+ { 37, 12, 3, 0, 0, }, /* 353 */
+ { 37, 1, 2, 0, 0, }, /* 354 */
+ { 37, 13, 12, 0, 0, }, /* 355 */
+ { 37, 7, 12, 0, 0, }, /* 356 */
+ { 37, 6, 12, 0, 0, }, /* 357 */
+ { 34, 7, 12, 0, 0, }, /* 358 */
+ { 34, 12, 3, 0, 0, }, /* 359 */
+ { 34, 10, 5, 0, 0, }, /* 360 */
+ { 34, 26, 12, 0, 0, }, /* 361 */
+ { 34, 21, 12, 0, 0, }, /* 362 */
+ { 34, 13, 12, 0, 0, }, /* 363 */
+ { 52, 7, 12, 0, 0, }, /* 364 */
+ { 39, 7, 12, 0, 0, }, /* 365 */
+ { 39, 13, 12, 0, 0, }, /* 366 */
+ { 39, 15, 12, 0, 0, }, /* 367 */
+ { 39, 26, 12, 0, 0, }, /* 368 */
+ { 31, 26, 12, 0, 0, }, /* 369 */
+ { 5, 7, 12, 0, 0, }, /* 370 */
+ { 5, 12, 3, 0, 0, }, /* 371 */
+ { 5, 10, 5, 0, 0, }, /* 372 */
+ { 5, 21, 12, 0, 0, }, /* 373 */
+ { 90, 7, 12, 0, 0, }, /* 374 */
+ { 90, 10, 5, 0, 0, }, /* 375 */
+ { 90, 12, 3, 0, 0, }, /* 376 */
+ { 90, 10, 12, 0, 0, }, /* 377 */
+ { 90, 13, 12, 0, 0, }, /* 378 */
+ { 90, 21, 12, 0, 0, }, /* 379 */
+ { 90, 6, 12, 0, 0, }, /* 380 */
+ { 27, 11, 3, 0, 0, }, /* 381 */
+ { 61, 12, 3, 0, 0, }, /* 382 */
+ { 61, 10, 5, 0, 0, }, /* 383 */
+ { 61, 7, 12, 0, 0, }, /* 384 */
+ { 61, 13, 12, 0, 0, }, /* 385 */
+ { 61, 21, 12, 0, 0, }, /* 386 */
+ { 61, 26, 12, 0, 0, }, /* 387 */
+ { 75, 12, 3, 0, 0, }, /* 388 */
+ { 75, 10, 5, 0, 0, }, /* 389 */
+ { 75, 7, 12, 0, 0, }, /* 390 */
+ { 75, 13, 12, 0, 0, }, /* 391 */
+ { 92, 7, 12, 0, 0, }, /* 392 */
+ { 92, 12, 3, 0, 0, }, /* 393 */
+ { 92, 10, 5, 0, 0, }, /* 394 */
+ { 92, 21, 12, 0, 0, }, /* 395 */
+ { 69, 7, 12, 0, 0, }, /* 396 */
+ { 69, 10, 5, 0, 0, }, /* 397 */
+ { 69, 12, 3, 0, 0, }, /* 398 */
+ { 69, 21, 12, 0, 0, }, /* 399 */
+ { 69, 13, 12, 0, 0, }, /* 400 */
+ { 72, 13, 12, 0, 0, }, /* 401 */
+ { 72, 7, 12, 0, 0, }, /* 402 */
+ { 72, 6, 12, 0, 0, }, /* 403 */
+ { 72, 21, 12, 0, 0, }, /* 404 */
+ { 75, 21, 12, 0, 0, }, /* 405 */
+ { 9, 10, 5, 0, 0, }, /* 406 */
+ { 9, 7, 12, 0, 0, }, /* 407 */
+ { 12, 5, 12, 0, 0, }, /* 408 */
+ { 12, 6, 12, 0, 0, }, /* 409 */
+ { 33, 5, 12, 0, 35332, }, /* 410 */
+ { 33, 5, 12, 0, 3814, }, /* 411 */
+ { 33, 9, 12, 63, 1, }, /* 412 */
+ { 33, 5, 12, 63, -1, }, /* 413 */
+ { 33, 5, 12, 63, -58, }, /* 414 */
+ { 33, 9, 12, 0, -7615, }, /* 415 */
+ { 19, 5, 12, 0, 8, }, /* 416 */
+ { 19, 9, 12, 0, -8, }, /* 417 */
+ { 19, 5, 12, 0, 74, }, /* 418 */
+ { 19, 5, 12, 0, 86, }, /* 419 */
+ { 19, 5, 12, 0, 100, }, /* 420 */
+ { 19, 5, 12, 0, 128, }, /* 421 */
+ { 19, 5, 12, 0, 112, }, /* 422 */
+ { 19, 5, 12, 0, 126, }, /* 423 */
+ { 19, 8, 12, 0, -8, }, /* 424 */
+ { 19, 5, 12, 0, 9, }, /* 425 */
+ { 19, 9, 12, 0, -74, }, /* 426 */
+ { 19, 8, 12, 0, -9, }, /* 427 */
+ { 19, 5, 12, 21, -7173, }, /* 428 */
+ { 19, 9, 12, 0, -86, }, /* 429 */
+ { 19, 9, 12, 0, -100, }, /* 430 */
+ { 19, 9, 12, 0, -112, }, /* 431 */
+ { 19, 9, 12, 0, -128, }, /* 432 */
+ { 19, 9, 12, 0, -126, }, /* 433 */
+ { 27, 1, 3, 0, 0, }, /* 434 */
+ { 9, 27, 2, 0, 0, }, /* 435 */
+ { 9, 28, 2, 0, 0, }, /* 436 */
+ { 9, 2, 2, 0, 0, }, /* 437 */
+ { 9, 9, 12, 0, 0, }, /* 438 */
+ { 9, 5, 12, 0, 0, }, /* 439 */
+ { 19, 9, 12, 67, -7517, }, /* 440 */
+ { 33, 9, 12, 71, -8383, }, /* 441 */
+ { 33, 9, 12, 75, -8262, }, /* 442 */
+ { 33, 9, 12, 0, 28, }, /* 443 */
+ { 33, 5, 12, 0, -28, }, /* 444 */
+ { 33, 14, 12, 0, 16, }, /* 445 */
+ { 33, 14, 12, 0, -16, }, /* 446 */
+ { 33, 14, 12, 0, 0, }, /* 447 */
+ { 9, 26, 12, 0, 26, }, /* 448 */
+ { 9, 26, 12, 0, -26, }, /* 449 */
+ { 4, 26, 12, 0, 0, }, /* 450 */
+ { 17, 9, 12, 0, 48, }, /* 451 */
+ { 17, 5, 12, 0, -48, }, /* 452 */
+ { 33, 9, 12, 0, -10743, }, /* 453 */
+ { 33, 9, 12, 0, -3814, }, /* 454 */
+ { 33, 9, 12, 0, -10727, }, /* 455 */
+ { 33, 5, 12, 0, -10795, }, /* 456 */
+ { 33, 5, 12, 0, -10792, }, /* 457 */
+ { 33, 9, 12, 0, -10780, }, /* 458 */
+ { 33, 9, 12, 0, -10749, }, /* 459 */
+ { 33, 9, 12, 0, -10783, }, /* 460 */
+ { 33, 9, 12, 0, -10782, }, /* 461 */
+ { 33, 9, 12, 0, -10815, }, /* 462 */
+ { 10, 5, 12, 0, 0, }, /* 463 */
+ { 10, 26, 12, 0, 0, }, /* 464 */
+ { 10, 12, 3, 0, 0, }, /* 465 */
+ { 10, 21, 12, 0, 0, }, /* 466 */
+ { 10, 15, 12, 0, 0, }, /* 467 */
+ { 16, 5, 12, 0, -7264, }, /* 468 */
+ { 58, 7, 12, 0, 0, }, /* 469 */
+ { 58, 6, 12, 0, 0, }, /* 470 */
+ { 58, 21, 12, 0, 0, }, /* 471 */
+ { 58, 12, 3, 0, 0, }, /* 472 */
+ { 22, 26, 12, 0, 0, }, /* 473 */
+ { 22, 6, 12, 0, 0, }, /* 474 */
+ { 22, 14, 12, 0, 0, }, /* 475 */
+ { 23, 10, 3, 0, 0, }, /* 476 */
+ { 26, 7, 12, 0, 0, }, /* 477 */
+ { 26, 6, 12, 0, 0, }, /* 478 */
+ { 29, 7, 12, 0, 0, }, /* 479 */
+ { 29, 6, 12, 0, 0, }, /* 480 */
+ { 3, 7, 12, 0, 0, }, /* 481 */
+ { 23, 7, 12, 0, 0, }, /* 482 */
+ { 23, 26, 12, 0, 0, }, /* 483 */
+ { 29, 26, 12, 0, 0, }, /* 484 */
+ { 22, 7, 12, 0, 0, }, /* 485 */
+ { 60, 7, 12, 0, 0, }, /* 486 */
+ { 60, 6, 12, 0, 0, }, /* 487 */
+ { 60, 26, 12, 0, 0, }, /* 488 */
+ { 85, 7, 12, 0, 0, }, /* 489 */
+ { 85, 6, 12, 0, 0, }, /* 490 */
+ { 85, 21, 12, 0, 0, }, /* 491 */
+ { 76, 7, 12, 0, 0, }, /* 492 */
+ { 76, 6, 12, 0, 0, }, /* 493 */
+ { 76, 21, 12, 0, 0, }, /* 494 */
+ { 76, 13, 12, 0, 0, }, /* 495 */
+ { 12, 7, 12, 0, 0, }, /* 496 */
+ { 12, 21, 12, 0, 0, }, /* 497 */
+ { 78, 7, 12, 0, 0, }, /* 498 */
+ { 78, 14, 12, 0, 0, }, /* 499 */
+ { 78, 12, 3, 0, 0, }, /* 500 */
+ { 78, 21, 12, 0, 0, }, /* 501 */
+ { 33, 9, 12, 0, -35332, }, /* 502 */
+ { 33, 9, 12, 0, -42280, }, /* 503 */
+ { 33, 9, 12, 0, -42308, }, /* 504 */
+ { 33, 9, 12, 0, -42319, }, /* 505 */
+ { 33, 9, 12, 0, -42315, }, /* 506 */
+ { 33, 9, 12, 0, -42305, }, /* 507 */
+ { 33, 9, 12, 0, -42258, }, /* 508 */
+ { 33, 9, 12, 0, -42282, }, /* 509 */
+ { 33, 9, 12, 0, -42261, }, /* 510 */
+ { 33, 9, 12, 0, 928, }, /* 511 */
+ { 48, 7, 12, 0, 0, }, /* 512 */
+ { 48, 12, 3, 0, 0, }, /* 513 */
+ { 48, 10, 5, 0, 0, }, /* 514 */
+ { 48, 26, 12, 0, 0, }, /* 515 */
+ { 64, 7, 12, 0, 0, }, /* 516 */
+ { 64, 21, 12, 0, 0, }, /* 517 */
+ { 74, 10, 5, 0, 0, }, /* 518 */
+ { 74, 7, 12, 0, 0, }, /* 519 */
+ { 74, 12, 3, 0, 0, }, /* 520 */
+ { 74, 21, 12, 0, 0, }, /* 521 */
+ { 74, 13, 12, 0, 0, }, /* 522 */
+ { 68, 13, 12, 0, 0, }, /* 523 */
+ { 68, 7, 12, 0, 0, }, /* 524 */
+ { 68, 12, 3, 0, 0, }, /* 525 */
+ { 68, 21, 12, 0, 0, }, /* 526 */
+ { 73, 7, 12, 0, 0, }, /* 527 */
+ { 73, 12, 3, 0, 0, }, /* 528 */
+ { 73, 10, 5, 0, 0, }, /* 529 */
+ { 73, 21, 12, 0, 0, }, /* 530 */
+ { 83, 12, 3, 0, 0, }, /* 531 */
+ { 83, 10, 5, 0, 0, }, /* 532 */
+ { 83, 7, 12, 0, 0, }, /* 533 */
+ { 83, 21, 12, 0, 0, }, /* 534 */
+ { 83, 13, 12, 0, 0, }, /* 535 */
+ { 38, 6, 12, 0, 0, }, /* 536 */
+ { 67, 7, 12, 0, 0, }, /* 537 */
+ { 67, 12, 3, 0, 0, }, /* 538 */
+ { 67, 10, 5, 0, 0, }, /* 539 */
+ { 67, 13, 12, 0, 0, }, /* 540 */
+ { 67, 21, 12, 0, 0, }, /* 541 */
+ { 91, 7, 12, 0, 0, }, /* 542 */
+ { 91, 12, 3, 0, 0, }, /* 543 */
+ { 91, 6, 12, 0, 0, }, /* 544 */
+ { 91, 21, 12, 0, 0, }, /* 545 */
+ { 86, 7, 12, 0, 0, }, /* 546 */
+ { 86, 10, 5, 0, 0, }, /* 547 */
+ { 86, 12, 3, 0, 0, }, /* 548 */
+ { 86, 21, 12, 0, 0, }, /* 549 */
+ { 86, 6, 12, 0, 0, }, /* 550 */
+ { 33, 5, 12, 0, -928, }, /* 551 */
+ { 8, 5, 12, 0, -38864, }, /* 552 */
+ { 86, 13, 12, 0, 0, }, /* 553 */
+ { 23, 7, 9, 0, 0, }, /* 554 */
+ { 23, 7, 10, 0, 0, }, /* 555 */
+ { 9, 4, 2, 0, 0, }, /* 556 */
+ { 9, 3, 12, 0, 0, }, /* 557 */
+ { 25, 25, 12, 0, 0, }, /* 558 */
+ { 0, 24, 12, 0, 0, }, /* 559 */
+ { 9, 6, 3, 0, 0, }, /* 560 */
+ { 35, 7, 12, 0, 0, }, /* 561 */
+ { 19, 14, 12, 0, 0, }, /* 562 */
+ { 19, 15, 12, 0, 0, }, /* 563 */
+ { 19, 26, 12, 0, 0, }, /* 564 */
+ { 70, 7, 12, 0, 0, }, /* 565 */
+ { 66, 7, 12, 0, 0, }, /* 566 */
+ { 41, 7, 12, 0, 0, }, /* 567 */
+ { 41, 15, 12, 0, 0, }, /* 568 */
+ { 18, 7, 12, 0, 0, }, /* 569 */
+ { 18, 14, 12, 0, 0, }, /* 570 */
+ { 117, 7, 12, 0, 0, }, /* 571 */
+ { 117, 12, 3, 0, 0, }, /* 572 */
+ { 59, 7, 12, 0, 0, }, /* 573 */
+ { 59, 21, 12, 0, 0, }, /* 574 */
+ { 42, 7, 12, 0, 0, }, /* 575 */
+ { 42, 21, 12, 0, 0, }, /* 576 */
+ { 42, 14, 12, 0, 0, }, /* 577 */
+ { 13, 9, 12, 0, 40, }, /* 578 */
+ { 13, 5, 12, 0, -40, }, /* 579 */
+ { 46, 7, 12, 0, 0, }, /* 580 */
+ { 44, 7, 12, 0, 0, }, /* 581 */
+ { 44, 13, 12, 0, 0, }, /* 582 */
+ { 105, 7, 12, 0, 0, }, /* 583 */
+ { 103, 7, 12, 0, 0, }, /* 584 */
+ { 103, 21, 12, 0, 0, }, /* 585 */
+ { 109, 7, 12, 0, 0, }, /* 586 */
+ { 11, 7, 12, 0, 0, }, /* 587 */
+ { 80, 7, 12, 0, 0, }, /* 588 */
+ { 80, 21, 12, 0, 0, }, /* 589 */
+ { 80, 15, 12, 0, 0, }, /* 590 */
+ { 119, 7, 12, 0, 0, }, /* 591 */
+ { 119, 26, 12, 0, 0, }, /* 592 */
+ { 119, 15, 12, 0, 0, }, /* 593 */
+ { 115, 7, 12, 0, 0, }, /* 594 */
+ { 115, 15, 12, 0, 0, }, /* 595 */
+ { 127, 7, 12, 0, 0, }, /* 596 */
+ { 127, 15, 12, 0, 0, }, /* 597 */
+ { 65, 7, 12, 0, 0, }, /* 598 */
+ { 65, 15, 12, 0, 0, }, /* 599 */
+ { 65, 21, 12, 0, 0, }, /* 600 */
+ { 71, 7, 12, 0, 0, }, /* 601 */
+ { 71, 21, 12, 0, 0, }, /* 602 */
+ { 97, 7, 12, 0, 0, }, /* 603 */
+ { 96, 7, 12, 0, 0, }, /* 604 */
+ { 96, 15, 12, 0, 0, }, /* 605 */
+ { 30, 7, 12, 0, 0, }, /* 606 */
+ { 30, 12, 3, 0, 0, }, /* 607 */
+ { 30, 15, 12, 0, 0, }, /* 608 */
+ { 30, 21, 12, 0, 0, }, /* 609 */
+ { 87, 7, 12, 0, 0, }, /* 610 */
+ { 87, 15, 12, 0, 0, }, /* 611 */
+ { 87, 21, 12, 0, 0, }, /* 612 */
+ { 116, 7, 12, 0, 0, }, /* 613 */
+ { 116, 15, 12, 0, 0, }, /* 614 */
+ { 111, 7, 12, 0, 0, }, /* 615 */
+ { 111, 26, 12, 0, 0, }, /* 616 */
+ { 111, 12, 3, 0, 0, }, /* 617 */
+ { 111, 15, 12, 0, 0, }, /* 618 */
+ { 111, 21, 12, 0, 0, }, /* 619 */
+ { 77, 7, 12, 0, 0, }, /* 620 */
+ { 77, 21, 12, 0, 0, }, /* 621 */
+ { 82, 7, 12, 0, 0, }, /* 622 */
+ { 82, 15, 12, 0, 0, }, /* 623 */
+ { 81, 7, 12, 0, 0, }, /* 624 */
+ { 81, 15, 12, 0, 0, }, /* 625 */
+ { 120, 7, 12, 0, 0, }, /* 626 */
+ { 120, 21, 12, 0, 0, }, /* 627 */
+ { 120, 15, 12, 0, 0, }, /* 628 */
+ { 88, 7, 12, 0, 0, }, /* 629 */
+ { 129, 9, 12, 0, 64, }, /* 630 */
+ { 129, 5, 12, 0, -64, }, /* 631 */
+ { 129, 15, 12, 0, 0, }, /* 632 */
+ { 0, 15, 12, 0, 0, }, /* 633 */
+ { 93, 10, 5, 0, 0, }, /* 634 */
+ { 93, 12, 3, 0, 0, }, /* 635 */
+ { 93, 7, 12, 0, 0, }, /* 636 */
+ { 93, 21, 12, 0, 0, }, /* 637 */
+ { 93, 15, 12, 0, 0, }, /* 638 */
+ { 93, 13, 12, 0, 0, }, /* 639 */
+ { 84, 12, 3, 0, 0, }, /* 640 */
+ { 84, 10, 5, 0, 0, }, /* 641 */
+ { 84, 7, 12, 0, 0, }, /* 642 */
+ { 84, 21, 12, 0, 0, }, /* 643 */
+ { 84, 1, 2, 0, 0, }, /* 644 */
+ { 100, 7, 12, 0, 0, }, /* 645 */
+ { 100, 13, 12, 0, 0, }, /* 646 */
+ { 95, 12, 3, 0, 0, }, /* 647 */
+ { 95, 7, 12, 0, 0, }, /* 648 */
+ { 95, 10, 5, 0, 0, }, /* 649 */
+ { 95, 13, 12, 0, 0, }, /* 650 */
+ { 95, 21, 12, 0, 0, }, /* 651 */
+ { 110, 7, 12, 0, 0, }, /* 652 */
+ { 110, 12, 3, 0, 0, }, /* 653 */
+ { 110, 21, 12, 0, 0, }, /* 654 */
+ { 99, 12, 3, 0, 0, }, /* 655 */
+ { 99, 10, 5, 0, 0, }, /* 656 */
+ { 99, 7, 12, 0, 0, }, /* 657 */
+ { 99, 21, 12, 0, 0, }, /* 658 */
+ { 99, 13, 12, 0, 0, }, /* 659 */
+ { 47, 15, 12, 0, 0, }, /* 660 */
+ { 107, 7, 12, 0, 0, }, /* 661 */
+ { 107, 10, 5, 0, 0, }, /* 662 */
+ { 107, 12, 3, 0, 0, }, /* 663 */
+ { 107, 21, 12, 0, 0, }, /* 664 */
+ { 128, 7, 12, 0, 0, }, /* 665 */
+ { 128, 21, 12, 0, 0, }, /* 666 */
+ { 108, 7, 12, 0, 0, }, /* 667 */
+ { 108, 12, 3, 0, 0, }, /* 668 */
+ { 108, 10, 5, 0, 0, }, /* 669 */
+ { 108, 13, 12, 0, 0, }, /* 670 */
+ { 106, 12, 3, 0, 0, }, /* 671 */
+ { 106, 10, 5, 0, 0, }, /* 672 */
+ { 106, 7, 12, 0, 0, }, /* 673 */
+ { 106, 10, 3, 0, 0, }, /* 674 */
+ { 123, 7, 12, 0, 0, }, /* 675 */
+ { 123, 10, 3, 0, 0, }, /* 676 */
+ { 123, 10, 5, 0, 0, }, /* 677 */
+ { 123, 12, 3, 0, 0, }, /* 678 */
+ { 123, 21, 12, 0, 0, }, /* 679 */
+ { 123, 13, 12, 0, 0, }, /* 680 */
+ { 122, 7, 12, 0, 0, }, /* 681 */
+ { 122, 10, 3, 0, 0, }, /* 682 */
+ { 122, 10, 5, 0, 0, }, /* 683 */
+ { 122, 12, 3, 0, 0, }, /* 684 */
+ { 122, 21, 12, 0, 0, }, /* 685 */
+ { 113, 7, 12, 0, 0, }, /* 686 */
+ { 113, 10, 5, 0, 0, }, /* 687 */
+ { 113, 12, 3, 0, 0, }, /* 688 */
+ { 113, 21, 12, 0, 0, }, /* 689 */
+ { 113, 13, 12, 0, 0, }, /* 690 */
+ { 101, 7, 12, 0, 0, }, /* 691 */
+ { 101, 12, 3, 0, 0, }, /* 692 */
+ { 101, 10, 5, 0, 0, }, /* 693 */
+ { 101, 13, 12, 0, 0, }, /* 694 */
+ { 125, 7, 12, 0, 0, }, /* 695 */
+ { 125, 12, 3, 0, 0, }, /* 696 */
+ { 125, 10, 5, 0, 0, }, /* 697 */
+ { 125, 13, 12, 0, 0, }, /* 698 */
+ { 125, 15, 12, 0, 0, }, /* 699 */
+ { 125, 21, 12, 0, 0, }, /* 700 */
+ { 125, 26, 12, 0, 0, }, /* 701 */
+ { 124, 9, 12, 0, 32, }, /* 702 */
+ { 124, 5, 12, 0, -32, }, /* 703 */
+ { 124, 13, 12, 0, 0, }, /* 704 */
+ { 124, 15, 12, 0, 0, }, /* 705 */
+ { 124, 7, 12, 0, 0, }, /* 706 */
+ { 121, 7, 12, 0, 0, }, /* 707 */
+ { 62, 7, 12, 0, 0, }, /* 708 */
+ { 62, 14, 12, 0, 0, }, /* 709 */
+ { 62, 21, 12, 0, 0, }, /* 710 */
+ { 79, 7, 12, 0, 0, }, /* 711 */
+ { 126, 7, 12, 0, 0, }, /* 712 */
+ { 114, 7, 12, 0, 0, }, /* 713 */
+ { 114, 13, 12, 0, 0, }, /* 714 */
+ { 114, 21, 12, 0, 0, }, /* 715 */
+ { 102, 7, 12, 0, 0, }, /* 716 */
+ { 102, 12, 3, 0, 0, }, /* 717 */
+ { 102, 21, 12, 0, 0, }, /* 718 */
+ { 118, 7, 12, 0, 0, }, /* 719 */
+ { 118, 12, 3, 0, 0, }, /* 720 */
+ { 118, 21, 12, 0, 0, }, /* 721 */
+ { 118, 26, 12, 0, 0, }, /* 722 */
+ { 118, 6, 12, 0, 0, }, /* 723 */
+ { 118, 13, 12, 0, 0, }, /* 724 */
+ { 118, 15, 12, 0, 0, }, /* 725 */
+ { 98, 7, 12, 0, 0, }, /* 726 */
+ { 98, 10, 5, 0, 0, }, /* 727 */
+ { 98, 12, 3, 0, 0, }, /* 728 */
+ { 98, 6, 12, 0, 0, }, /* 729 */
+ { 104, 7, 12, 0, 0, }, /* 730 */
+ { 104, 26, 12, 0, 0, }, /* 731 */
+ { 104, 12, 3, 0, 0, }, /* 732 */
+ { 104, 21, 12, 0, 0, }, /* 733 */
+ { 9, 10, 3, 0, 0, }, /* 734 */
+ { 19, 12, 3, 0, 0, }, /* 735 */
+ { 130, 26, 12, 0, 0, }, /* 736 */
+ { 130, 12, 3, 0, 0, }, /* 737 */
+ { 130, 21, 12, 0, 0, }, /* 738 */
+ { 112, 7, 12, 0, 0, }, /* 739 */
+ { 112, 15, 12, 0, 0, }, /* 740 */
+ { 112, 12, 3, 0, 0, }, /* 741 */
+ { 9, 26, 11, 0, 0, }, /* 742 */
+ { 26, 26, 12, 0, 0, }, /* 743 */
+};
+
+const uint8_t PRIV(ucd_stage1)[] = { /* 8704 bytes */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 41, 42, 43, 44, 45, /* U+1000 */
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, /* U+1800 */
+ 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 71, 72, 73, 71, 74, 75, /* U+2000 */
+ 76, 76, 66, 77, 66, 66, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, /* U+2800 */
+ 88, 89, 90, 91, 92, 93, 94, 71, 95, 95, 95, 95, 95, 95, 95, 95, /* U+3000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+3800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+4000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 95, 95, 95, 95, /* U+4800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+5000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+5800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+6000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+6800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+7000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+7800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+8000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+8800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+9000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 97, /* U+9800 */
+ 98, 99, 99, 99, 99, 99, 99, 99, 99,100,101,101,102,103,104,105, /* U+A000 */
+106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,114, /* U+A800 */
+115,116,117,118,119,120,114,115,116,117,118,119,120,114,115,116, /* U+B000 */
+117,118,119,120,114,115,116,117,118,119,120,114,115,116,117,118, /* U+B800 */
+119,120,114,115,116,117,118,119,120,114,115,116,117,118,119,120, /* U+C000 */
+114,115,116,117,118,119,120,114,115,116,117,118,119,120,114,115, /* U+C800 */
+116,117,118,119,120,114,115,116,117,118,119,120,114,115,116,121, /* U+D000 */
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, /* U+D800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+E000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+E800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F000 */
+123,123, 95, 95,124,125,126,127,128,128,129,130,131,132,133,134, /* U+F800 */
+135,136,137,138,139,140,141,142,143,144,145,139,146,146,147,139, /* U+10000 */
+148,149,150,151,152,153,154,155,156,157,139,139,158,139,139,139, /* U+10800 */
+159,160,161,162,163,164,165,139,139,166,139,167,168,169,170,139, /* U+11000 */
+139,171,139,139,139,172,139,139,139,139,139,139,139,139,139,139, /* U+11800 */
+173,173,173,173,173,173,173,174,175,173,176,139,139,139,139,139, /* U+12000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+12800 */
+177,177,177,177,177,177,177,177,178,139,139,139,139,139,139,139, /* U+13000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+13800 */
+139,139,139,139,139,139,139,139,179,179,179,179,180,139,139,139, /* U+14000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+14800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+15000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+15800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+16000 */
+181,181,181,181,182,183,184,185,139,139,139,139,139,139,186,187, /* U+16800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+17000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+17800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+18000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+18800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+19000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+19800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1A800 */
+188,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1B000 */
+139,139,139,139,139,139,139,139,189,190,139,139,139,139,139,139, /* U+1B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1C800 */
+ 71,191,192,193,194,139,195,139,196,197,198,199,200,201,202,203, /* U+1D000 */
+204,204,204,204,205,206,139,139,139,139,139,139,139,139,139,139, /* U+1D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1E000 */
+207,208,139,139,139,139,139,139,139,139,139,139,209,210,139,139, /* U+1E800 */
+211,212,213,214,215,139, 71,216, 71, 71,217,218, 71,219,220,221, /* U+1F000 */
+222,223,224,225,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1F800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+20000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+20800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+21000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+21800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+22000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+22800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+23000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+23800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+24000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+24800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+25000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+25800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+26000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+26800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+27000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+27800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+28000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+28800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+29000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+29800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,226, 95, 95, /* U+2A000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+2A800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,227, 95, /* U+2B000 */
+228, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+2B800 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+2C000 */
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,229,139,139, /* U+2C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2F000 */
+ 95, 95, 95, 95,230,139,139,139,139,139,139,139,139,139,139,139, /* U+2F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+30000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+30800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+31000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+31800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+32000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+32800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+33000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+33800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+34000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+34800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+35000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+35800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+36000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+36800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+37000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+37800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+38000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+38800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+39000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+39800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3A800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3B000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3F000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+40000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+40800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+41000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+41800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+42000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+42800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+43000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+43800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+44000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+44800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+45000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+45800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+46000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+46800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+47000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+47800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+48000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+48800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+49000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+49800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4A800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4B000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4F000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+50000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+50800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+51000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+51800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+52000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+52800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+53000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+53800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+54000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+54800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+55000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+55800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+56000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+56800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+57000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+57800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+58000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+58800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+59000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+59800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5A800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5B000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5F000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+60000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+60800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+61000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+61800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+62000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+62800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+63000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+63800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+64000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+64800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+65000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+65800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+66000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+66800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+67000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+67800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+68000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+68800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+69000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+69800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6A800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6B000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6F000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+70000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+70800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+71000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+71800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+72000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+72800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+73000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+73800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+74000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+74800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+75000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+75800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+76000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+76800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+77000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+77800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+78000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+78800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+79000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+79800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7A800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7B000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7F000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+80000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+80800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+81000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+81800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+82000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+82800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+83000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+83800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+84000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+84800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+85000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+85800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+86000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+86800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+87000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+87800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+88000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+88800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+89000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+89800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8A800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8B000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8F000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+90000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+90800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+91000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+91800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+92000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+92800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+93000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+93800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+94000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+94800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+95000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+95800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+96000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+96800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+97000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+97800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+98000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+98800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+99000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+99800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9A000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9A800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9B000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9B800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9C000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9C800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9D000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9D800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9E000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9E800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9F000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9F800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A0000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A0800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A1000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A1800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A2000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A2800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A3000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A3800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A4000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A4800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A5000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A5800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A6000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A6800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A7000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A7800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A8000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A8800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A9000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A9800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AA000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AA800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AB000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AB800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AC000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AC800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AD000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AD800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AE000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AE800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AF000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AF800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B0000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B0800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B1000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B1800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B2000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B2800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B3000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B3800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B4000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B4800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B5000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B5800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B6000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B6800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B7000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B7800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B8000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B8800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B9000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B9800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BA000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BA800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BB000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BB800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BC000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BC800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BD000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BD800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BE000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BE800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BF000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BF800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C0000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C0800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C1000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C1800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C2000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C2800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C3000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C3800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C4000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C4800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C5000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C5800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C6000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C6800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C7000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C7800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C8000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C8800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C9000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C9800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CA000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CA800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CB000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CB800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CC000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CC800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CD000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CD800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CE000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CE800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CF000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CF800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D0000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D0800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D1000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D1800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D2000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D2800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D3000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D3800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D4000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D4800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D5000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D5800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D6000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D6800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D7000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D7800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D8000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D8800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D9000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D9800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DA000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DA800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DB000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DB800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DC000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DC800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DD000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DD800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DE000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DE800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DF000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DF800 */
+231,232,233,234,232,232,232,232,232,232,232,232,232,232,232,232, /* U+E0000 */
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, /* U+E0800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E1000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E1800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E2000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E2800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E3000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E3800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E4000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E4800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E5000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E5800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E6000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E6800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E7000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E7800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E8000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E8800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E9000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E9800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EA000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EA800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EB000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EB800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EC000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EC800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+ED000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+ED800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EE000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EE800 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EF000 */
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EF800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F0000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F0800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F1000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F1800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F2000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F2800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F3000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F3800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F4000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F4800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F5000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F5800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F6000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F6800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F7000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F7800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F8000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F8800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F9000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F9800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FA000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FA800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FB000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FB800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FC000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FC800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FD000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FD800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FE000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FE800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FF000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,235, /* U+FF800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+100000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+100800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+101000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+101800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+102000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+102800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+103000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+103800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+104000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+104800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+105000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+105800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+106000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+106800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+107000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+107800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+108000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+108800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+109000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+109800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10A000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10A800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10B000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10B800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10C000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10C800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10D000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10D800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10E000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10E800 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10F000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,235, /* U+10F800 */
+};
+
+const uint16_t PRIV(ucd_stage2)[] = { /* 60416 bytes, block = 128 */
+/* block 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 4, 4, 4, 5, 4, 4, 4, 6, 7, 4, 8, 4, 9, 4, 4,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 4, 8, 8, 8, 4,
+ 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11,
+ 11, 11, 11, 13, 11, 11, 11, 11, 11, 11, 11, 6, 4, 7, 14, 15,
+ 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16,
+ 16, 16, 16, 18, 16, 16, 16, 16, 16, 16, 16, 6, 8, 7, 8, 0,
+
+/* block 1 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 4, 5, 5, 5, 5, 19, 4, 14, 19, 20, 21, 8, 22, 19, 14,
+ 19, 8, 23, 23, 14, 24, 4, 4, 14, 23, 20, 25, 23, 23, 23, 4,
+ 11, 11, 11, 11, 11, 26, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 8, 11, 11, 11, 11, 11, 11, 11, 27,
+ 16, 16, 16, 16, 16, 28, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 16, 16, 16, 16, 29,
+
+/* block 2 */
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 32, 33, 30, 31, 30, 31, 30, 31, 33, 30, 31, 30, 31, 30, 31, 30,
+ 31, 30, 31, 30, 31, 30, 31, 30, 31, 33, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 34, 30, 31, 30, 31, 30, 31, 35,
+
+/* block 3 */
+ 36, 37, 30, 31, 30, 31, 38, 30, 31, 39, 39, 30, 31, 33, 40, 41,
+ 42, 30, 31, 39, 43, 44, 45, 46, 30, 31, 47, 33, 45, 48, 49, 50,
+ 30, 31, 30, 31, 30, 31, 51, 30, 31, 51, 33, 33, 30, 31, 51, 30,
+ 31, 52, 52, 30, 31, 30, 31, 53, 30, 31, 33, 20, 30, 31, 33, 54,
+ 20, 20, 20, 20, 55, 56, 57, 58, 59, 60, 61, 62, 63, 30, 31, 30,
+ 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 64, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 33, 65, 66, 67, 30, 31, 68, 69, 30, 31, 30, 31, 30, 31, 30, 31,
+
+/* block 4 */
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 70, 33, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 33, 33, 33, 33, 33, 33, 71, 30, 31, 72, 73, 74,
+ 74, 30, 31, 75, 76, 77, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 78, 79, 80, 81, 82, 33, 83, 83, 33, 84, 33, 85, 86, 33, 33, 33,
+ 83, 87, 33, 88, 33, 89, 90, 33, 91, 92, 33, 93, 94, 33, 33, 92,
+ 33, 95, 96, 33, 33, 97, 33, 33, 33, 33, 33, 33, 33, 98, 33, 33,
+
+/* block 5 */
+ 99, 33, 33, 99, 33, 33, 33,100, 99,101,102,102,103, 33, 33, 33,
+ 33, 33,104, 33, 20, 33, 33, 33, 33, 33, 33, 33, 33,105,106, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+107,107,107,107,107,107,107,107,107,108,108,108,108,108,108,108,
+108,108, 14, 14, 14, 14,108,108,108,108,108,108,108,108,108,108,
+108,108, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+107,107,107,107,107, 14, 14, 14, 14, 14,109,109,108, 14,108, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+
+/* block 6 */
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,111,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+112,113,112,113,108,114,112,113,115,115,116,117,117,117, 4,118,
+
+/* block 7 */
+115,115,115,115,114, 14,119, 4,120,120,120,115,121,115,122,122,
+123,124,125,124,124,126,124,124,127,128,129,124,130,124,124,124,
+131,132,115,133,124,124,134,124,124,135,124,124,136,137,137,137,
+123,138,139,138,138,140,138,138,141,142,143,138,144,138,138,138,
+145,146,147,148,138,138,149,138,138,150,138,138,151,152,152,153,
+154,155,156,156,156,157,158,159,112,113,112,113,112,113,112,113,
+112,113,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+162,163,164,165,166,167,168,112,113,169,112,113,123,170,170,170,
+
+/* block 8 */
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+
+/* block 9 */
+175,176,177,178,178,110,110,178,179,179,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+180,175,176,175,176,175,176,175,176,175,176,175,176,175,176,181,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+
+/* block 10 */
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+115,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,115,115,183,184,184,184,184,184,184,
+115,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+
+/* block 11 */
+185,185,185,185,185,185,185,186,115, 4,187,115,115,188,188,189,
+115,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,191,190,
+192,190,190,192,190,190,192,190,115,115,115,115,115,115,115,115,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,115,115,115,115,115,
+193,193,193,192,192,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 12 */
+194,194,194,194,194, 22,195,195,195,196,196,197, 4,196,198,198,
+199,199,199,199,199,199,199,199,199,199,199, 4, 22,115,196, 4,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+108,200,200,200,200,200,200,200,200,200,200,110,110,110,110,110,
+110,110,110,110,110,110,199,199,199,199,199,199,199,199,199,199,
+201,201,201,201,201,201,201,201,201,201,196,196,196,196,200,200,
+110,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+
+/* block 13 */
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,196,200,199,199,199,199,199,199,199, 22,198,199,
+199,199,199,199,199,202,202,199,199,198,199,199,199,199,200,200,
+201,201,201,201,201,201,201,201,201,201,200,200,200,198,198,200,
+
+/* block 14 */
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,115,204,
+205,206,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,115,115,205,205,205,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+
+/* block 15 */
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,208,208,208,208,208,208,208,208,208,208,
+208,207,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+209,209,209,209,209,209,209,209,209,209,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,211,211,211,211,211,
+211,211,211,211,212,212,213,214,214,214,212,115,115,115,115,115,
+
+/* block 16 */
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,216,216,216,216,217,216,216,216,216,216,
+216,216,216,216,217,216,216,216,217,216,216,216,216,216,115,115,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,115,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,220,220,220,115,115,221,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 17 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+
+/* block 18 */
+222,222,222,223,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,222,223,222,224,223,223,
+223,222,222,222,222,222,222,222,222,223,223,223,223,222,223,223,
+224,110,110,222,222,222,222,222,224,224,224,224,224,224,224,224,
+224,224,222,222, 4, 4,225,225,225,225,225,225,225,225,225,225,
+226,227,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+
+/* block 19 */
+228,229,230,230,115,228,228,228,228,228,228,228,228,115,115,228,
+228,115,115,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,115,228,228,228,228,228,228,
+228,115,228,115,115,115,228,228,228,228,115,115,229,228,231,230,
+230,229,229,229,229,115,115,230,230,115,115,230,230,229,228,115,
+115,115,115,115,115,115,115,231,115,115,115,115,228,228,115,228,
+228,228,229,229,115,115,232,232,232,232,232,232,232,232,232,232,
+228,228,233,233,234,234,234,234,234,234,235,233,115,115,115,115,
+
+/* block 20 */
+115,236,236,237,115,238,238,238,238,238,238,115,115,115,115,238,
+238,115,115,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,115,238,238,238,238,238,238,
+238,115,238,238,115,238,238,115,238,238,115,115,236,115,237,237,
+237,236,236,115,115,115,115,236,236,115,115,236,236,236,115,115,
+115,236,115,115,115,115,115,115,115,238,238,238,238,115,238,115,
+115,115,115,115,115,115,239,239,239,239,239,239,239,239,239,239,
+236,236,238,238,238,236,115,115,115,115,115,115,115,115,115,115,
+
+/* block 21 */
+115,240,240,241,115,242,242,242,242,242,242,242,242,242,115,242,
+242,242,115,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,115,242,242,242,242,242,242,
+242,115,242,242,115,242,242,242,242,242,115,115,240,242,241,241,
+241,240,240,240,240,240,115,240,240,241,115,241,241,240,115,115,
+242,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+242,242,240,240,115,115,243,243,243,243,243,243,243,243,243,243,
+244,245,115,115,115,115,115,115,115,242,115,115,115,115,115,115,
+
+/* block 22 */
+115,246,247,247,115,248,248,248,248,248,248,248,248,115,115,248,
+248,115,115,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,115,248,248,248,248,248,248,
+248,115,248,248,115,248,248,248,248,248,115,115,246,248,249,246,
+247,246,246,246,246,115,115,247,247,115,115,247,247,246,115,115,
+115,115,115,115,115,115,246,249,115,115,115,115,248,248,115,248,
+248,248,246,246,115,115,250,250,250,250,250,250,250,250,250,250,
+251,248,252,252,252,252,252,252,115,115,115,115,115,115,115,115,
+
+/* block 23 */
+115,115,253,254,115,254,254,254,254,254,254,115,115,115,254,254,
+254,115,254,254,254,254,115,115,115,254,254,115,254,115,254,254,
+115,115,115,254,254,115,115,115,254,254,254,115,115,115,254,254,
+254,254,254,254,254,254,254,254,254,254,115,115,115,115,255,256,
+253,256,256,115,115,115,256,256,256,115,256,256,256,253,115,115,
+254,115,115,115,115,115,115,255,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,257,257,257,257,257,257,257,257,257,257,
+258,258,258,259,259,259,259,259,259,260,259,115,115,115,115,115,
+
+/* block 24 */
+261,262,262,262,115,263,263,263,263,263,263,263,263,115,263,263,
+263,115,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
+263,263,263,263,263,263,263,263,263,115,263,263,263,263,263,263,
+263,263,263,263,263,263,263,263,263,263,115,115,115,263,261,261,
+261,262,262,262,262,115,261,261,261,115,261,261,261,261,115,115,
+115,115,115,115,115,261,261,115,263,263,263,115,115,115,115,115,
+263,263,261,261,115,115,264,264,264,264,264,264,264,264,264,264,
+115,115,115,115,115,115,115,115,265,265,265,265,265,265,265,266,
+
+/* block 25 */
+115,267,268,268,115,269,269,269,269,269,269,269,269,115,269,269,
+269,115,269,269,269,269,269,269,269,269,269,269,269,269,269,269,
+269,269,269,269,269,269,269,269,269,115,269,269,269,269,269,269,
+269,269,269,269,115,269,269,269,269,269,115,115,267,269,268,267,
+268,268,270,268,268,115,267,268,268,115,268,268,267,267,115,115,
+115,115,115,115,115,270,270,115,115,115,115,115,115,115,269,115,
+269,269,267,267,115,115,271,271,271,271,271,271,271,271,271,271,
+115,269,269,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 26 */
+115,272,273,273,115,274,274,274,274,274,274,274,274,115,274,274,
+274,115,274,274,274,274,274,274,274,274,274,274,274,274,274,274,
+274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,
+274,274,274,274,274,274,274,274,274,274,274,115,115,274,275,273,
+273,272,272,272,272,115,273,273,273,115,273,273,273,272,274,115,
+115,115,115,115,115,115,115,275,115,115,115,115,115,115,115,274,
+274,274,272,272,115,115,276,276,276,276,276,276,276,276,276,276,
+277,277,277,277,277,277,115,115,115,278,274,274,274,274,274,274,
+
+/* block 27 */
+115,115,279,279,115,280,280,280,280,280,280,280,280,280,280,280,
+280,280,280,280,280,280,280,115,115,115,280,280,280,280,280,280,
+280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
+280,280,115,280,280,280,280,280,280,280,280,280,115,280,115,115,
+280,280,280,280,280,280,280,115,115,115,281,115,115,115,115,282,
+279,279,281,281,281,115,281,115,279,279,279,279,279,279,279,282,
+115,115,115,115,115,115,283,283,283,283,283,283,283,283,283,283,
+115,115,279,279,284,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 28 */
+115,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
+285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
+285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
+285,286,285,287,286,286,286,286,286,286,286,115,115,115,115, 5,
+285,285,285,285,285,285,288,286,286,286,286,286,286,286,286,289,
+290,290,290,290,290,290,290,290,290,290,289,289,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 29 */
+115,291,291,115,291,115,115,291,291,115,291,115,115,291,115,115,
+115,115,115,115,291,291,291,291,115,291,291,291,291,291,291,291,
+115,291,291,291,115,291,115,291,115,115,291,291,115,291,291,291,
+291,292,291,293,292,292,292,292,292,292,115,292,292,291,115,115,
+291,291,291,291,291,115,294,115,292,292,292,292,292,292,115,115,
+295,295,295,295,295,295,295,295,295,295,115,115,291,291,291,291,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 30 */
+296,297,297,297,298,298,298,298,298,298,298,298,298,298,298,298,
+298,298,298,297,298,297,297,297,299,299,297,297,297,297,297,297,
+300,300,300,300,300,300,300,300,300,300,301,301,301,301,301,301,
+301,301,301,301,297,299,297,299,297,299,302,303,302,303,304,304,
+296,296,296,296,296,296,296,296,115,296,296,296,296,296,296,296,
+296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,
+296,296,296,296,296,296,296,296,296,296,296,296,296,115,115,115,
+115,299,299,299,299,299,299,299,299,299,299,299,299,299,299,304,
+
+/* block 31 */
+299,299,299,299,299,298,299,299,296,296,296,296,296,299,299,299,
+299,299,299,299,299,299,299,299,115,299,299,299,299,299,299,299,
+299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
+299,299,299,299,299,299,299,299,299,299,299,299,299,115,297,297,
+297,297,297,297,297,297,299,297,297,297,297,297,297,115,297,297,
+298,298,298,298,298, 19, 19, 19, 19,298,298,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 32 */
+305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+305,305,305,305,305,305,305,305,305,305,305,306,306,307,307,307,
+307,308,307,307,307,307,307,307,306,307,307,308,308,307,307,305,
+309,309,309,309,309,309,309,309,309,309,310,310,310,310,310,310,
+305,305,305,305,305,305,308,308,307,307,305,305,305,305,307,307,
+307,305,306,306,306,305,305,306,306,306,306,306,306,306,305,305,
+305,307,307,307,307,305,305,305,305,305,305,305,305,305,305,305,
+
+/* block 33 */
+305,305,307,306,308,307,307,306,306,306,306,306,306,307,305,306,
+309,309,309,309,309,309,309,309,309,309,306,306,306,307,311,311,
+312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,
+312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,
+312,312,312,312,312,312,115,312,115,115,115,115,115,312,115,115,
+313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,313,313,313,313,313,313, 4,314,313,313,313,
+
+/* block 34 */
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
+316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
+
+/* block 35 */
+316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
+316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
+316,316,316,316,316,316,316,316,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+
+/* block 36 */
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,115,318,318,318,318,115,115,
+318,318,318,318,318,318,318,115,318,115,318,318,318,318,115,115,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+
+/* block 37 */
+318,318,318,318,318,318,318,318,318,115,318,318,318,318,115,115,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,115,318,318,318,318,115,115,318,318,318,318,318,318,318,115,
+318,115,318,318,318,318,115,115,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+
+/* block 38 */
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,115,318,318,318,318,115,115,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,115,115,319,319,319,
+320,320,320,320,320,320,320,320,320,321,321,321,321,321,321,321,
+321,321,321,321,321,321,321,321,321,321,321,321,321,115,115,115,
+
+/* block 39 */
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+322,322,322,322,322,322,322,322,322,322,115,115,115,115,115,115,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+324,324,324,324,324,324,115,115,325,325,325,325,325,325,115,115,
+
+/* block 40 */
+326,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+
+/* block 41 */
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+
+/* block 42 */
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,328,328,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+
+/* block 43 */
+329,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,330,330,330,330,330,330,330,331,332,115,115,115,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333, 4, 4, 4,334,334,
+334,333,333,333,333,333,333,333,333,115,115,115,115,115,115,115,
+
+/* block 44 */
+335,335,335,335,335,335,335,335,335,335,335,335,335,115,335,335,
+335,335,336,336,336,115,115,115,115,115,115,115,115,115,115,115,
+337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,
+337,337,338,338,338, 4, 4,115,115,115,115,115,115,115,115,115,
+339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
+339,339,340,340,115,115,115,115,115,115,115,115,115,115,115,115,
+341,341,341,341,341,341,341,341,341,341,341,341,341,115,341,341,
+341,115,342,342,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 45 */
+343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
+343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
+343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
+343,343,343,343,344,344,345,344,344,344,344,344,344,344,345,345,
+345,345,345,345,345,345,344,345,345,344,344,344,344,344,344,344,
+344,344,344,344,346,346,346,347,346,346,346,348,343,344,115,115,
+349,349,349,349,349,349,349,349,349,349,115,115,115,115,115,115,
+350,350,350,350,350,350,350,350,350,350,115,115,115,115,115,115,
+
+/* block 46 */
+351,351, 4, 4,351, 4,352,351,351,351,351,353,353,353,354,115,
+355,355,355,355,355,355,355,355,355,355,115,115,115,115,115,115,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,357,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,115,115,115,115,115,115,115,115,
+
+/* block 47 */
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,353,356,115,115,115,115,115,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,115,115,115,115,115,115,115,115,115,115,
+
+/* block 48 */
+358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,115,
+359,359,359,360,360,360,360,359,359,360,360,360,115,115,115,115,
+360,360,359,360,360,360,360,360,360,359,359,359,115,115,115,115,
+361,115,115,115,362,362,363,363,363,363,363,363,363,363,363,363,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,115,115,
+364,364,364,364,364,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 49 */
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,365,365,115,115,115,115,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,115,115,115,115,115,115,
+366,366,366,366,366,366,366,366,366,366,367,115,115,115,368,368,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+
+/* block 50 */
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,371,371,372,372,371,115,115,373,373,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,375,376,375,376,376,376,376,376,376,376,115,
+376,377,376,377,377,376,376,376,376,376,376,376,376,375,375,375,
+375,375,375,376,376,376,376,376,376,376,376,376,376,115,115,376,
+
+/* block 51 */
+378,378,378,378,378,378,378,378,378,378,115,115,115,115,115,115,
+378,378,378,378,378,378,378,378,378,378,115,115,115,115,115,115,
+379,379,379,379,379,379,379,380,379,379,379,379,379,379,115,115,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,381,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 52 */
+382,382,382,382,383,384,384,384,384,384,384,384,384,384,384,384,
+384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
+384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
+384,384,384,384,382,383,382,382,382,382,382,383,382,383,383,383,
+383,383,382,383,383,384,384,384,384,384,384,384,115,115,115,115,
+385,385,385,385,385,385,385,385,385,385,386,386,386,386,386,386,
+386,387,387,387,387,387,387,387,387,387,387,382,382,382,382,382,
+382,382,382,382,387,387,387,387,387,387,387,387,387,115,115,115,
+
+/* block 53 */
+388,388,389,390,390,390,390,390,390,390,390,390,390,390,390,390,
+390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,
+390,389,388,388,388,388,389,389,388,388,389,388,388,388,390,390,
+391,391,391,391,391,391,391,391,391,391,390,390,390,390,390,390,
+392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
+392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
+392,392,392,392,392,392,393,394,393,393,394,394,394,393,394,393,
+393,393,394,394,115,115,115,115,115,115,115,115,395,395,395,395,
+
+/* block 54 */
+396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
+396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
+396,396,396,396,397,397,397,397,397,397,397,397,398,398,398,398,
+398,398,398,398,397,397,398,398,115,115,115,399,399,399,399,399,
+400,400,400,400,400,400,400,400,400,400,115,115,115,396,396,396,
+401,401,401,401,401,401,401,401,401,401,402,402,402,402,402,402,
+402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
+402,402,402,402,402,402,402,402,403,403,403,403,403,403,404,404,
+
+/* block 55 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+405,405,405,405,405,405,405,405,115,115,115,115,115,115,115,115,
+110,110,110, 4,110,110,110,110,110,110,110,110,110,110,110,110,
+110,406,110,110,110,110,110,110,110,407,407,407,407,110,407,407,
+407,407,406,406,110,407,407,115,110,110,115,115,115,115,115,115,
+
+/* block 56 */
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33,123,123,123,123,123,408,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,116,116,116,
+116,116,107,107,107,107,116,116,116,116,116, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33,409,410, 33, 33, 33,411, 33, 33,
+
+/* block 57 */
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,116,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,115,115,115,115,115,115,110,110,110,110,
+
+/* block 58 */
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+412,413, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+
+/* block 59 */
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 33, 33, 33, 33, 33,414, 33, 33,415, 33,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+
+/* block 60 */
+416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
+416,416,416,416,416,416,115,115,417,417,417,417,417,417,115,115,
+416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
+416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
+416,416,416,416,416,416,115,115,417,417,417,417,417,417,115,115,
+123,416,123,416,123,416,123,416,115,417,115,417,115,417,115,417,
+416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
+418,418,419,419,419,419,420,420,421,421,422,422,423,423,115,115,
+
+/* block 61 */
+416,416,416,416,416,416,416,416,424,424,424,424,424,424,424,424,
+416,416,416,416,416,416,416,416,424,424,424,424,424,424,424,424,
+416,416,416,416,416,416,416,416,424,424,424,424,424,424,424,424,
+416,416,123,425,123,115,123,123,417,417,426,426,427,114,428,114,
+114,114,123,425,123,115,123,123,429,429,429,429,427,114,114,114,
+416,416,123,123,115,115,123,123,417,417,430,430,115,114,114,114,
+416,416,123,123,123,164,123,123,417,417,431,431,169,114,114,114,
+115,115,123,425,123,115,123,123,432,432,433,433,427,114,114,115,
+
+/* block 62 */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 22,434,434, 22, 22,
+ 9, 9, 9, 9, 9, 9, 4, 4, 21, 25, 6, 21, 21, 25, 6, 21,
+ 4, 4, 4, 4, 4, 4, 4, 4,435,436, 22, 22, 22, 22, 22, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 25, 4, 4, 4, 4, 15,
+ 15, 4, 4, 4, 8, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 8, 4, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
+ 22, 22, 22, 22, 22,437, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 23,107,115,115, 23, 23, 23, 23, 23, 23, 8, 8, 8, 6, 7,107,
+
+/* block 63 */
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 8, 8, 8, 6, 7,115,
+107,107,107,107,107,107,107,107,107,107,107,107,107,115,115,115,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+110,110,110,110,110,110,110,110,110,110,110,110,110,381,381,381,
+381,110,381,381,381,110,110,110,110,110,110,110,110,110,110,110,
+110,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 64 */
+ 19, 19,438, 19, 19, 19, 19,438, 19, 19,439,438,438,438,439,439,
+438,438,438,439, 19,438, 19, 19, 8,438,438,438,438,438, 19, 19,
+ 19, 19, 19, 19,438, 19,440, 19,438, 19,441,442,438,438, 19,439,
+438,438,443,438,439,407,407,407,407,439, 19, 19,439,439,438,438,
+ 8, 8, 8, 8, 8,438,439,439,439,439, 19, 8, 19, 19,444, 19,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,
+446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,
+
+/* block 65 */
+447,447,447, 30, 31,447,447,447,447, 23, 19, 19,115,115,115,115,
+ 8, 8, 8, 8, 8, 19, 19, 19, 19, 19, 8, 8, 19, 19, 19, 19,
+ 8, 19, 19, 8, 19, 19, 8, 19, 19, 19, 19, 19, 19, 19, 8, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8,
+ 19, 19, 8, 19, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+/* block 66 */
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+/* block 67 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 6, 7, 6, 7, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 8, 8, 19, 19, 19, 19, 19, 19, 19, 6, 7, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 19, 19, 19,
+
+/* block 68 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8,
+ 8, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,
+
+/* block 69 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+
+/* block 70 */
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19,448,448,448,448,448,448,448,448,448,448,
+448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,
+449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,
+449,449,449,449,449,449,449,449,449,449, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+
+/* block 71 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 72 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 8, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 8, 8, 8, 8,
+
+/* block 73 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 74 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 6, 7, 6, 7, 6, 7, 6, 7,
+ 6, 7, 6, 7, 6, 7, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+
+/* block 75 */
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 8, 8, 8, 8, 8, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+/* block 76 */
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+
+/* block 77 */
+ 8, 8, 8, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6,
+ 7, 6, 7, 6, 7, 6, 7, 6, 7, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 6, 7, 6, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 7, 8, 8,
+
+/* block 78 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 19, 19, 8, 8, 8, 8, 8, 8, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,115,115, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 79 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19,115,115, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19,115, 19, 19, 19, 19, 19, 19,
+ 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115, 19, 19, 19, 19,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 80 */
+451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
+451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
+451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,115,
+452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,
+452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,
+452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,115,
+ 30, 31,453,454,455,456,457, 30, 31, 30, 31, 30, 31,458,459,460,
+461, 33, 30, 31, 33, 30, 31, 33, 33, 33, 33, 33,107,107,462,462,
+
+/* block 81 */
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,463,464,464,464,464,464,464,160,161,160,161,465,
+465,465,160,161,115,115,115,115,115,466,466,466,466,467,466,466,
+
+/* block 82 */
+468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,
+468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,
+468,468,468,468,468,468,115,468,115,115,115,115,115,468,115,115,
+469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
+469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
+469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
+469,469,469,469,469,469,469,469,115,115,115,115,115,115,115,470,
+471,115,115,115,115,115,115,115,115,115,115,115,115,115,115,472,
+
+/* block 83 */
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,115,115,115,115,115,115,115,115,115,
+318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
+318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
+318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
+318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+
+/* block 84 */
+ 4, 4, 21, 25, 21, 25, 4, 4, 4, 21, 25, 4, 21, 25, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 9, 4, 4, 9, 4, 21, 25, 4, 4,
+ 21, 25, 6, 7, 6, 7, 6, 7, 6, 7, 4, 4, 4, 4, 4,108,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 9, 4, 4, 4, 4,
+ 9, 4, 6,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 85 */
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,115,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 86 */
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+
+/* block 87 */
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
+
+/* block 88 */
+ 3, 4, 4, 4, 19,474,407,475, 6, 7, 6, 7, 6, 7, 6, 7,
+ 6, 7, 19, 19, 6, 7, 6, 7, 6, 7, 6, 7, 9, 6, 7, 7,
+ 19,475,475,475,475,475,475,475,475,475,110,110,110,110,476,476,
+ 9,108,108,108,108,108, 19, 19,475,475,475,474,407, 4, 19, 19,
+115,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
+477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
+477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
+477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
+
+/* block 89 */
+477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
+477,477,477,477,477,477,477,115,115,110,110, 14, 14,478,478,477,
+ 9,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479, 4,108,480,480,479,
+
+/* block 90 */
+115,115,115,115,115,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,115,115,
+115,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+
+/* block 91 */
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,115,
+ 19, 19, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+
+/* block 92 */
+483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
+483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,115,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 23, 23, 23, 23, 23, 23, 23, 23,
+ 19, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
+483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, 19,
+
+/* block 93 */
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,115,
+
+/* block 94 */
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 95 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+
+/* block 96 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 97 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 98 */
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,487,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+
+/* block 99 */
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+
+/* block 100 */
+486,486,486,486,486,486,486,486,486,486,486,486,486,115,115,115,
+488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
+488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
+488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
+488,488,488,488,488,488,488,115,115,115,115,115,115,115,115,115,
+489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489,489,489,489,489,489,489,489,490,490,490,490,490,490,491,491,
+
+/* block 101 */
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+
+/* block 102 */
+492,492,492,492,492,492,492,492,492,492,492,492,493,494,494,494,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+495,495,495,495,495,495,495,495,495,495,492,492,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,496,178,
+179,179,179,497,178,178,178,178,178,178,178,178,178,178,497,409,
+
+/* block 103 */
+175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+175,176,175,176,175,176,175,176,175,176,175,176,409,409,178,178,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,499,499,499,499,499,499,499,499,499,499,
+500,500,501,501,501,501,501,501,115,115,115,115,115,115,115,115,
+
+/* block 104 */
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14,108,108,108,108,108,108,108,108,108,
+ 14, 14, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 33, 33, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+107, 33, 33, 33, 33, 33, 33, 33, 33, 30, 31, 30, 31,502, 30, 31,
+
+/* block 105 */
+ 30, 31, 30, 31, 30, 31, 30, 31,108, 14, 14, 30, 31,503, 33, 20,
+ 30, 31, 30, 31, 33, 33, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,504,505,506,507,115,115,
+508,509,510,511, 30, 31, 30, 31,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115, 20,107,107, 33, 20, 20, 20, 20, 20,
+
+/* block 106 */
+512,512,513,512,512,512,513,512,512,512,512,513,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,514,514,513,513,514,515,515,515,515,115,115,115,115,
+ 23, 23, 23, 23, 23, 23, 19, 19, 5, 19,115,115,115,115,115,115,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,517,517,517,517,115,115,115,115,115,115,115,115,
+
+/* block 107 */
+518,518,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,518,518,518,518,518,518,518,518,518,518,518,518,
+518,518,518,518,520,115,115,115,115,115,115,115,115,115,521,521,
+522,522,522,522,522,522,522,522,522,522,115,115,115,115,115,115,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,224,224,224,224,224,224,226,226,226,224,226,224,115,115,
+
+/* block 108 */
+523,523,523,523,523,523,523,523,523,523,524,524,524,524,524,524,
+524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,
+524,524,524,524,524,524,525,525,525,525,525,525,525,525, 4,526,
+527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,
+527,527,527,527,527,527,527,528,528,528,528,528,528,528,528,528,
+528,528,529,529,115,115,115,115,115,115,115,115,115,115,115,530,
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+315,315,315,315,315,315,315,315,315,315,315,315,315,115,115,115,
+
+/* block 109 */
+531,531,531,532,533,533,533,533,533,533,533,533,533,533,533,533,
+533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,
+533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,
+533,533,533,531,532,532,531,531,531,531,532,532,531,532,532,532,
+532,534,534,534,534,534,534,534,534,534,534,534,534,534,115,108,
+535,535,535,535,535,535,535,535,535,535,115,115,115,115,534,534,
+305,305,305,305,305,307,536,305,305,305,305,305,305,305,305,305,
+309,309,309,309,309,309,309,309,309,309,305,305,305,305,305,115,
+
+/* block 110 */
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,538,538,538,538,538,538,539,
+539,538,538,539,539,538,538,115,115,115,115,115,115,115,115,115,
+537,537,537,538,537,537,537,537,537,537,537,537,538,539,115,115,
+540,540,540,540,540,540,540,540,540,540,115,115,541,541,541,541,
+305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+536,305,305,305,305,305,305,311,311,311,305,306,307,306,305,305,
+
+/* block 111 */
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+543,542,543,543,543,542,542,543,543,542,542,542,542,542,543,543,
+542,543,542,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,542,542,544,545,545,
+546,546,546,546,546,546,546,546,546,546,546,547,548,548,547,547,
+549,549,546,550,550,547,548,115,115,115,115,115,115,115,115,115,
+
+/* block 112 */
+115,318,318,318,318,318,318,115,115,318,318,318,318,318,318,115,
+115,318,318,318,318,318,318,115,115,115,115,115,115,115,115,115,
+318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33,551, 33, 33, 33, 33, 33, 33, 33, 14,107,107,107,107,
+ 33, 33, 33, 33, 33,123,115,115,115,115,115,115,115,115,115,115,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+
+/* block 113 */
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
+546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
+546,546,546,547,547,548,547,547,548,547,547,549,547,548,115,115,
+553,553,553,553,553,553,553,553,553,553,115,115,115,115,115,115,
+
+/* block 114 */
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+
+/* block 115 */
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+
+/* block 116 */
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+
+/* block 117 */
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+
+/* block 118 */
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+
+/* block 119 */
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+
+/* block 120 */
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+
+/* block 121 */
+555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,115,115,115,115,115,115,115,115,115,115,115,115,
+316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
+316,316,316,316,316,316,316,115,115,115,115,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,115,115,115,115,
+
+/* block 122 */
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+
+/* block 123 */
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+
+/* block 124 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,115,115,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+
+/* block 125 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 126 */
+ 33, 33, 33, 33, 33, 33, 33,115,115,115,115,115,115,115,115,115,
+115,115,115,186,186,186,186,186,115,115,115,115,115,193,190,193,
+193,193,193,193,193,193,193,193,193,558,193,193,193,193,193,193,
+193,193,193,193,193,193,193,115,193,193,193,193,193,115,193,115,
+193,193,115,193,193,115,193,193,193,193,193,193,193,193,193,193,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+
+/* block 127 */
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
+559,559,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+
+/* block 128 */
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+
+/* block 129 */
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200, 7, 6,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+
+/* block 130 */
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+115,115,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+200,200,200,200,200,200,200,200,200,200,200,200,197,198,115,115,
+
+/* block 131 */
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+ 4, 4, 4, 4, 4, 4, 4, 6, 7, 4,115,115,115,115,115,115,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,178,178,
+ 4, 9, 9, 15, 15, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6,
+ 7, 6, 7, 6, 7, 4, 4, 6, 7, 4, 4, 4, 4, 15, 15, 15,
+ 4, 4, 4,115, 4, 4, 4, 4, 9, 6, 7, 6, 7, 6, 7, 4,
+ 4, 4, 8, 9, 8, 8, 8,115, 4, 5, 4, 4,115,115,115,115,
+200,200,200,200,200,115,200,200,200,200,200,200,200,200,200,200,
+
+/* block 132 */
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,115,115, 22,
+
+/* block 133 */
+115, 4, 4, 4, 5, 4, 4, 4, 6, 7, 4, 8, 4, 9, 4, 4,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 4, 8, 8, 8, 4,
+ 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 6, 4, 7, 14, 15,
+ 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 6, 8, 7, 8, 6,
+ 7, 4, 6, 7, 4, 4,479,479,479,479,479,479,479,479,479,479,
+108,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+
+/* block 134 */
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,560,560,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,115,
+115,115,482,482,482,482,482,482,115,115,482,482,482,482,482,482,
+115,115,482,482,482,482,482,482,115,115,482,482,482,115,115,115,
+ 5, 5, 8, 14, 19, 5, 5,115, 19, 8, 8, 8, 8, 19, 19,115,
+437,437,437,437,437,437,437,437,437, 22, 22, 22, 19, 19,115,115,
+
+/* block 135 */
+561,561,561,561,561,561,561,561,561,561,561,561,115,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,115,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,115,561,561,115,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,115,115,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 136 */
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,115,115,115,115,115,
+
+/* block 137 */
+ 4, 4, 4,115,115,115,115, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23,115,115,115, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,563,563,563,563,564,564,564,564,564,564,564,
+
+/* block 138 */
+564,564,564,564,564,564,564,564,564,564,563,563,564,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
+564,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,110,115,115,
+
+/* block 139 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 140 */
+565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,
+565,565,565,565,565,565,565,565,565,565,565,565,565,115,115,115,
+566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
+566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
+566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
+566,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+110, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,115,115,115,115,
+
+/* block 141 */
+567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,
+567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,
+568,568,568,568,115,115,115,115,115,115,115,115,115,115,115,115,
+569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+569,570,569,569,569,569,569,569,569,569,570,115,115,115,115,115,
+571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
+571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
+571,571,571,571,571,571,572,572,572,572,572,115,115,115,115,115,
+
+/* block 142 */
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,115,574,
+575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,
+575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,
+575,575,575,575,115,115,115,115,575,575,575,575,575,575,575,575,
+576,577,577,577,577,577,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 143 */
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,579,579,579,579,579,579,579,579,
+579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,
+579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+
+/* block 144 */
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,115,115,
+582,582,582,582,582,582,582,582,582,582,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 145 */
+583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
+583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
+583,583,583,583,583,583,583,583,115,115,115,115,115,115,115,115,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,584,115,115,115,115,115,115,115,115,115,115,115,585,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 146 */
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+
+/* block 147 */
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,115,115,115,115,115,115,115,115,115,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,115,115,115,115,115,115,115,115,115,115,
+586,586,586,586,586,586,586,586,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 148 */
+587,587,587,587,587,587,115,115,587,115,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,115,587,587,115,115,115,587,115,115,587,
+588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,
+588,588,588,588,588,588,115,589,590,590,590,590,590,590,590,590,
+591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
+591,591,591,591,591,591,591,592,592,593,593,593,593,593,593,593,
+
+/* block 149 */
+594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,
+594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,115,
+115,115,115,115,115,115,115,595,595,595,595,595,595,595,595,595,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,115,596,596,115,115,115,115,115,597,597,597,597,597,
+
+/* block 150 */
+598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,
+598,598,598,598,598,598,599,599,599,599,599,599,115,115,115,600,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,115,115,115,115,115,602,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 151 */
+603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,
+603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,
+604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,
+604,604,604,604,604,604,604,604,115,115,115,115,605,605,604,604,
+605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
+115,115,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
+605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
+605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
+
+/* block 152 */
+606,607,607,607,115,607,607,115,115,115,115,115,607,607,607,607,
+606,606,606,606,115,606,606,606,115,606,606,606,606,606,606,606,
+606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,
+606,606,606,606,115,115,115,115,607,607,607,115,115,115,115,607,
+608,608,608,608,608,608,608,608,115,115,115,115,115,115,115,115,
+609,609,609,609,609,609,609,609,609,115,115,115,115,115,115,115,
+610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,
+610,610,610,610,610,610,610,610,610,610,610,610,610,611,611,612,
+
+/* block 153 */
+613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,
+613,613,613,613,613,613,613,613,613,613,613,613,613,614,614,614,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+615,615,615,615,615,615,615,615,616,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,617,617,115,115,115,115,618,618,618,618,618,
+619,619,619,619,619,619,619,115,115,115,115,115,115,115,115,115,
+
+/* block 154 */
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
+620,620,620,620,620,620,115,115,115,621,621,621,621,621,621,621,
+622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,
+622,622,622,622,622,622,115,115,623,623,623,623,623,623,623,623,
+624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,
+624,624,624,115,115,115,115,115,625,625,625,625,625,625,625,625,
+
+/* block 155 */
+626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,
+626,626,115,115,115,115,115,115,115,627,627,627,627,115,115,115,
+115,115,115,115,115,115,115,115,115,628,628,628,628,628,628,628,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 156 */
+629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
+629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
+629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
+629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
+629,629,629,629,629,629,629,629,629,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 157 */
+630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,115,115,115,115,115,115,115,115,115,115,115,115,115,
+631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
+631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
+631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
+631,631,631,115,115,115,115,115,115,115,632,632,632,632,632,632,
+
+/* block 158 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,
+633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,115,
+
+/* block 159 */
+634,635,634,636,636,636,636,636,636,636,636,636,636,636,636,636,
+636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,
+636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,
+636,636,636,636,636,636,636,636,635,635,635,635,635,635,635,635,
+635,635,635,635,635,635,635,637,637,637,637,637,637,637,115,115,
+115,115,638,638,638,638,638,638,638,638,638,638,638,638,638,638,
+638,638,638,638,638,638,639,639,639,639,639,639,639,639,639,639,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,635,
+
+/* block 160 */
+640,640,641,642,642,642,642,642,642,642,642,642,642,642,642,642,
+642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,
+642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,
+641,641,641,640,640,640,640,641,641,640,640,643,643,644,643,643,
+643,643,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,
+645,645,645,645,645,645,645,645,645,115,115,115,115,115,115,115,
+646,646,646,646,646,646,646,646,646,646,115,115,115,115,115,115,
+
+/* block 161 */
+647,647,647,648,648,648,648,648,648,648,648,648,648,648,648,648,
+648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,
+648,648,648,648,648,648,648,647,647,647,647,647,649,647,647,647,
+647,647,647,647,647,115,650,650,650,650,650,650,650,650,650,650,
+651,651,651,651,115,115,115,115,115,115,115,115,115,115,115,115,
+652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
+652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
+652,652,652,653,654,654,652,115,115,115,115,115,115,115,115,115,
+
+/* block 162 */
+655,655,656,657,657,657,657,657,657,657,657,657,657,657,657,657,
+657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+657,657,657,656,656,656,655,655,655,655,655,655,655,655,655,656,
+656,657,657,657,657,658,658,658,658,658,655,655,655,658,115,115,
+659,659,659,659,659,659,659,659,659,659,657,658,657,658,658,658,
+115,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,
+660,660,660,660,660,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 163 */
+661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
+661,661,115,661,661,661,661,661,661,661,661,661,661,661,661,661,
+661,661,661,661,661,661,661,661,661,661,661,661,662,662,662,663,
+663,663,662,662,663,662,663,663,664,664,664,664,664,664,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 164 */
+665,665,665,665,665,665,665,115,665,115,665,665,665,665,115,665,
+665,665,665,665,665,665,665,665,665,665,665,665,665,665,115,665,
+665,665,665,665,665,665,665,665,665,666,115,115,115,115,115,115,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,668,
+669,669,669,668,668,668,668,668,668,668,668,115,115,115,115,115,
+670,670,670,670,670,670,670,670,670,670,115,115,115,115,115,115,
+
+/* block 165 */
+671,671,672,672,115,673,673,673,673,673,673,673,673,115,115,673,
+673,115,115,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,115,673,673,673,673,673,673,
+673,115,673,673,115,673,673,673,673,673,115,115,671,673,674,672,
+671,672,672,672,672,115,115,672,672,115,115,672,672,672,115,115,
+673,115,115,115,115,115,115,674,115,115,115,115,115,673,673,673,
+673,673,672,672,115,115,671,671,671,671,671,671,671,115,115,115,
+671,671,671,671,671,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 166 */
+675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
+675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
+675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
+676,677,677,678,678,678,678,678,678,677,678,677,677,676,677,678,
+678,677,678,678,675,675,679,675,115,115,115,115,115,115,115,115,
+680,680,680,680,680,680,680,680,680,680,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 167 */
+681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,
+681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,
+681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,682,
+683,683,684,684,684,684,115,115,683,683,683,683,684,684,683,684,
+684,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
+685,685,685,685,685,685,685,685,681,681,681,681,684,684,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 168 */
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+687,687,687,688,688,688,688,688,688,688,688,687,687,688,687,688,
+688,689,689,689,686,115,115,115,115,115,115,115,115,115,115,115,
+690,690,690,690,690,690,690,690,690,690,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 169 */
+691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
+691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
+691,691,691,691,691,691,691,691,691,691,691,692,693,692,693,693,
+692,692,692,692,692,692,693,692,115,115,115,115,115,115,115,115,
+694,694,694,694,694,694,694,694,694,694,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 170 */
+695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
+695,695,695,695,695,695,695,695,695,695,115,115,115,696,696,696,
+697,697,696,696,696,696,697,696,696,696,696,696,115,115,115,115,
+698,698,698,698,698,698,698,698,698,698,699,699,700,700,700,701,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 171 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
+704,704,704,704,704,704,704,704,704,704,705,705,705,705,705,705,
+705,705,705,115,115,115,115,115,115,115,115,115,115,115,115,706,
+
+/* block 172 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,707,115,115,115,115,115,115,115,
+
+/* block 173 */
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+
+/* block 174 */
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 175 */
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,115,
+710,710,710,710,710,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 176 */
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 177 */
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+
+/* block 178 */
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 179 */
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+
+/* block 180 */
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 181 */
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+
+/* block 182 */
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,115,115,115,115,115,115,115,
+713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,
+713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,115,
+714,714,714,714,714,714,714,714,714,714,115,115,115,115,715,715,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 183 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
+716,716,716,716,716,716,716,716,716,716,716,716,716,716,115,115,
+717,717,717,717,717,718,115,115,115,115,115,115,115,115,115,115,
+
+/* block 184 */
+719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
+719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
+719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
+720,720,720,720,720,720,720,721,721,721,721,721,722,722,722,722,
+723,723,723,723,721,722,115,115,115,115,115,115,115,115,115,115,
+724,724,724,724,724,724,724,724,724,724,115,725,725,725,725,725,
+725,725,115,719,719,719,719,719,719,719,719,719,719,719,719,719,
+719,719,719,719,719,719,719,719,115,115,115,115,115,719,719,719,
+
+/* block 185 */
+719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 186 */
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
+726,726,726,726,726,115,115,115,115,115,115,115,115,115,115,115,
+726,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
+727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
+727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,115,
+
+/* block 187 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,728,
+728,728,728,729,729,729,729,729,729,729,729,729,729,729,729,729,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 188 */
+479,477,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 189 */
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,115,115,115,115,115,
+730,730,730,730,730,730,730,730,730,730,730,730,730,115,115,115,
+
+/* block 190 */
+730,730,730,730,730,730,730,730,730,115,115,115,115,115,115,115,
+730,730,730,730,730,730,730,730,730,730,115,115,731,732,732,733,
+ 22, 22, 22, 22,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 191 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,
+
+/* block 192 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19,115,115, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19,734,406,110,110,110, 19, 19, 19,406,734,734,
+734,734,734, 22, 22, 22, 22, 22, 22, 22, 22,110,110,110,110,110,
+
+/* block 193 */
+110,110,110, 19, 19,110,110,110,110,110,110,110, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,110,110,110,110, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 194 */
+564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+564,564,735,735,735,564,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 195 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 196 */
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,439,439,
+439,439,439,439,439,115,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+
+/* block 197 */
+438,438,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,438,115,438,438,
+115,115,438,115,115,438,438,115,115,438,438,438,438,115,438,438,
+438,438,438,438,438,438,439,439,439,439,115,439,115,439,439,439,
+439,439,439,439,115,439,439,439,439,439,439,439,439,439,439,439,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+
+/* block 198 */
+439,439,439,439,438,438,115,438,438,438,438,115,115,438,438,438,
+438,438,438,438,438,115,438,438,438,438,438,438,438,115,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,438,438,115,438,438,438,438,115,
+438,438,438,438,438,115,438,115,115,115,438,438,438,438,438,438,
+438,115,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+
+/* block 199 */
+438,438,438,438,438,438,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+
+/* block 200 */
+439,439,439,439,439,439,439,439,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+
+/* block 201 */
+438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,115,115,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438, 8,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439, 8,439,439,439,439,
+439,439,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438, 8,439,439,439,439,
+
+/* block 202 */
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439, 8,439,439,439,439,439,439,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438, 8,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439, 8,
+439,439,439,439,439,439,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, 8,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+
+/* block 203 */
+439,439,439,439,439,439,439,439,439, 8,439,439,439,439,439,439,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438, 8,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439, 8,439,439,439,439,439,439,438,439,115,115, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+
+/* block 204 */
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+
+/* block 205 */
+737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,737,737,737,737,737,737,736,736,736,736,737,737,737,737,737,
+737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,737,737,737,737,737,737,737,737,737,737,737,737,736,736,736,
+736,736,736,736,736,737,736,736,736,736,736,736,736,736,736,736,
+
+/* block 206 */
+736,736,736,736,737,736,736,738,738,738,738,738,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,737,737,737,737,737,
+115,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 207 */
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+
+/* block 208 */
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,115,115,740,740,740,740,740,740,740,740,740,
+741,741,741,741,741,741,741,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 209 */
+200,200,200,200,115,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+115,200,200,115,200,115,115,200,115,200,200,200,200,200,200,200,
+200,200,200,115,200,200,200,200,115,200,115,200,115,115,115,115,
+115,115,200,115,115,115,115,200,115,200,115,200,115,200,200,200,
+115,200,200,115,200,115,115,200,115,200,115,200,115,200,115,200,
+115,200,200,115,200,115,115,200,200,200,200,115,200,200,200,200,
+200,200,200,115,200,200,200,200,115,200,200,200,200,115,200,115,
+
+/* block 210 */
+200,200,200,200,200,200,200,200,200,200,115,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,115,115,115,115,
+115,200,200,200,115,200,200,200,200,200,115,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+195,195,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 211 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 212 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,
+115, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+115, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+115, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,
+
+/* block 213 */
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 214 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,742,742,742,742,742,742,742,742,742,742,
+742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
+
+/* block 215 */
+743, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,
+ 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 216 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 14, 14, 14, 14, 14,
+
+/* block 217 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115, 19, 19, 19, 19, 19,
+
+/* block 218 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,115, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 219 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,
+ 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 220 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 221 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 222 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 223 */
+ 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 224 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 225 */
+ 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 226 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 227 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,115,115,115,115,115,115,115,115,115,115,115,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+
+/* block 228 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,115,115,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+
+/* block 229 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 230 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 231 */
+437, 22,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+
+/* block 232 */
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+
+/* block 233 */
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+
+/* block 234 */
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+
+/* block 235 */
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,115,115,
+
+};
+
+#if UCD_BLOCK_SIZE != 128
+#error Please correct UCD_BLOCK_SIZE in pcre2_internal.h
+#endif
+#endif /* SUPPORT_UNICODE */
+
+#endif /* PCRE2_PCRE2TEST */
diff --git a/thirdparty/pcre2/src/pcre2_ucp.h b/thirdparty/pcre2/src/pcre2_ucp.h
new file mode 100644
index 0000000000..02e5012c29
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_ucp.h
@@ -0,0 +1,268 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#ifndef PCRE2_UCP_H_IDEMPOTENT_GUARD
+#define PCRE2_UCP_H_IDEMPOTENT_GUARD
+
+/* This file contains definitions of the property values that are returned by
+the UCD access macros. New values that are added for new releases of Unicode
+should always be at the end of each enum, for backwards compatibility.
+
+IMPORTANT: Note also that the specific numeric values of the enums have to be
+the same as the values that are generated by the maint/MultiStage2.py script,
+where the equivalent property descriptive names are listed in vectors.
+
+ALSO: The specific values of the first two enums are assumed for the table
+called catposstab in pcre2_compile.c. */
+
+/* These are the general character categories. */
+
+enum {
+ ucp_C, /* Other */
+ ucp_L, /* Letter */
+ ucp_M, /* Mark */
+ ucp_N, /* Number */
+ ucp_P, /* Punctuation */
+ ucp_S, /* Symbol */
+ ucp_Z /* Separator */
+};
+
+/* These are the particular character categories. */
+
+enum {
+ ucp_Cc, /* Control */
+ ucp_Cf, /* Format */
+ ucp_Cn, /* Unassigned */
+ ucp_Co, /* Private use */
+ ucp_Cs, /* Surrogate */
+ ucp_Ll, /* Lower case letter */
+ ucp_Lm, /* Modifier letter */
+ ucp_Lo, /* Other letter */
+ ucp_Lt, /* Title case letter */
+ ucp_Lu, /* Upper case letter */
+ ucp_Mc, /* Spacing mark */
+ ucp_Me, /* Enclosing mark */
+ ucp_Mn, /* Non-spacing mark */
+ ucp_Nd, /* Decimal number */
+ ucp_Nl, /* Letter number */
+ ucp_No, /* Other number */
+ ucp_Pc, /* Connector punctuation */
+ ucp_Pd, /* Dash punctuation */
+ ucp_Pe, /* Close punctuation */
+ ucp_Pf, /* Final punctuation */
+ ucp_Pi, /* Initial punctuation */
+ ucp_Po, /* Other punctuation */
+ ucp_Ps, /* Open punctuation */
+ ucp_Sc, /* Currency symbol */
+ ucp_Sk, /* Modifier symbol */
+ ucp_Sm, /* Mathematical symbol */
+ ucp_So, /* Other symbol */
+ ucp_Zl, /* Line separator */
+ ucp_Zp, /* Paragraph separator */
+ ucp_Zs /* Space separator */
+};
+
+/* These are grapheme break properties. Note that the code for processing them
+assumes that the values are less than 16. If more values are added that take
+the number to 16 or more, the code will have to be rewritten. */
+
+enum {
+ ucp_gbCR, /* 0 */
+ ucp_gbLF, /* 1 */
+ ucp_gbControl, /* 2 */
+ ucp_gbExtend, /* 3 */
+ ucp_gbPrepend, /* 4 */
+ ucp_gbSpacingMark, /* 5 */
+ ucp_gbL, /* 6 Hangul syllable type L */
+ ucp_gbV, /* 7 Hangul syllable type V */
+ ucp_gbT, /* 8 Hangul syllable type T */
+ ucp_gbLV, /* 9 Hangul syllable type LV */
+ ucp_gbLVT, /* 10 Hangul syllable type LVT */
+ ucp_gbRegionalIndicator, /* 11 */
+ ucp_gbOther /* 12 */
+};
+
+/* These are the script identifications. */
+
+enum {
+ ucp_Arabic,
+ ucp_Armenian,
+ ucp_Bengali,
+ ucp_Bopomofo,
+ ucp_Braille,
+ ucp_Buginese,
+ ucp_Buhid,
+ ucp_Canadian_Aboriginal,
+ ucp_Cherokee,
+ ucp_Common,
+ ucp_Coptic,
+ ucp_Cypriot,
+ ucp_Cyrillic,
+ ucp_Deseret,
+ ucp_Devanagari,
+ ucp_Ethiopic,
+ ucp_Georgian,
+ ucp_Glagolitic,
+ ucp_Gothic,
+ ucp_Greek,
+ ucp_Gujarati,
+ ucp_Gurmukhi,
+ ucp_Han,
+ ucp_Hangul,
+ ucp_Hanunoo,
+ ucp_Hebrew,
+ ucp_Hiragana,
+ ucp_Inherited,
+ ucp_Kannada,
+ ucp_Katakana,
+ ucp_Kharoshthi,
+ ucp_Khmer,
+ ucp_Lao,
+ ucp_Latin,
+ ucp_Limbu,
+ ucp_Linear_B,
+ ucp_Malayalam,
+ ucp_Mongolian,
+ ucp_Myanmar,
+ ucp_New_Tai_Lue,
+ ucp_Ogham,
+ ucp_Old_Italic,
+ ucp_Old_Persian,
+ ucp_Oriya,
+ ucp_Osmanya,
+ ucp_Runic,
+ ucp_Shavian,
+ ucp_Sinhala,
+ ucp_Syloti_Nagri,
+ ucp_Syriac,
+ ucp_Tagalog,
+ ucp_Tagbanwa,
+ ucp_Tai_Le,
+ ucp_Tamil,
+ ucp_Telugu,
+ ucp_Thaana,
+ ucp_Thai,
+ ucp_Tibetan,
+ ucp_Tifinagh,
+ ucp_Ugaritic,
+ ucp_Yi,
+ /* New for Unicode 5.0: */
+ ucp_Balinese,
+ ucp_Cuneiform,
+ ucp_Nko,
+ ucp_Phags_Pa,
+ ucp_Phoenician,
+ /* New for Unicode 5.1: */
+ ucp_Carian,
+ ucp_Cham,
+ ucp_Kayah_Li,
+ ucp_Lepcha,
+ ucp_Lycian,
+ ucp_Lydian,
+ ucp_Ol_Chiki,
+ ucp_Rejang,
+ ucp_Saurashtra,
+ ucp_Sundanese,
+ ucp_Vai,
+ /* New for Unicode 5.2: */
+ ucp_Avestan,
+ ucp_Bamum,
+ ucp_Egyptian_Hieroglyphs,
+ ucp_Imperial_Aramaic,
+ ucp_Inscriptional_Pahlavi,
+ ucp_Inscriptional_Parthian,
+ ucp_Javanese,
+ ucp_Kaithi,
+ ucp_Lisu,
+ ucp_Meetei_Mayek,
+ ucp_Old_South_Arabian,
+ ucp_Old_Turkic,
+ ucp_Samaritan,
+ ucp_Tai_Tham,
+ ucp_Tai_Viet,
+ /* New for Unicode 6.0.0: */
+ ucp_Batak,
+ ucp_Brahmi,
+ ucp_Mandaic,
+ /* New for Unicode 6.1.0: */
+ ucp_Chakma,
+ ucp_Meroitic_Cursive,
+ ucp_Meroitic_Hieroglyphs,
+ ucp_Miao,
+ ucp_Sharada,
+ ucp_Sora_Sompeng,
+ ucp_Takri,
+ /* New for Unicode 7.0.0: */
+ ucp_Bassa_Vah,
+ ucp_Caucasian_Albanian,
+ ucp_Duployan,
+ ucp_Elbasan,
+ ucp_Grantha,
+ ucp_Khojki,
+ ucp_Khudawadi,
+ ucp_Linear_A,
+ ucp_Mahajani,
+ ucp_Manichaean,
+ ucp_Mende_Kikakui,
+ ucp_Modi,
+ ucp_Mro,
+ ucp_Nabataean,
+ ucp_Old_North_Arabian,
+ ucp_Old_Permic,
+ ucp_Pahawh_Hmong,
+ ucp_Palmyrene,
+ ucp_Psalter_Pahlavi,
+ ucp_Pau_Cin_Hau,
+ ucp_Siddham,
+ ucp_Tirhuta,
+ ucp_Warang_Citi,
+ /* New for Unicode 8.0.0: */
+ ucp_Ahom,
+ ucp_Anatolian_Hieroglyphs,
+ ucp_Hatran,
+ ucp_Multani,
+ ucp_Old_Hungarian,
+ ucp_SignWriting
+};
+
+#endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */
+
+/* End of pcre2_ucp.h */
diff --git a/thirdparty/pcre2/src/pcre2_valid_utf.c b/thirdparty/pcre2/src/pcre2_valid_utf.c
new file mode 100644
index 0000000000..3e18f1200b
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_valid_utf.c
@@ -0,0 +1,398 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function for validating UTF character
+strings. This file is also #included by the pcre2test program, which uses
+macros to change names from _pcre2_xxx to xxxx, thereby avoiding name clashes
+with the library. In this case, PCRE2_PCRE2TEST is defined. */
+
+#ifndef PCRE2_PCRE2TEST /* We're compiling the library */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "pcre2_internal.h"
+#endif /* PCRE2_PCRE2TEST */
+
+
+#ifndef SUPPORT_UNICODE
+/*************************************************
+* Dummy function when Unicode is not supported *
+*************************************************/
+
+/* This function should never be called when Unicode is not supported. */
+
+int
+PRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)
+{
+(void)string;
+(void)length;
+(void)erroroffset;
+return 0;
+}
+#else /* UTF is supported */
+
+
+
+/*************************************************
+* Validate a UTF string *
+*************************************************/
+
+/* This function is called (optionally) at the start of compile or match, to
+check that a supposed UTF string is actually valid. The early check means
+that subsequent code can assume it is dealing with a valid string. The check
+can be turned off for maximum performance, but the consequences of supplying an
+invalid string are then undefined.
+
+Arguments:
+ string points to the string
+ length length of string
+ errp pointer to an error position offset variable
+
+Returns: == 0 if the string is a valid UTF string
+ != 0 otherwise, setting the offset of the bad character
+*/
+
+int
+PRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)
+{
+PCRE2_SPTR p;
+uint32_t c;
+
+/* ----------------- Check a UTF-8 string ----------------- */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+
+/* Originally, this function checked according to RFC 2279, allowing for values
+in the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were
+in the canonical format. Once somebody had pointed out RFC 3629 to me (it
+obsoletes 2279), additional restrictions were applied. The values are now
+limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
+subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte
+characters is still checked. Error returns are as follows:
+
+PCRE2_ERROR_UTF8_ERR1 Missing 1 byte at the end of the string
+PCRE2_ERROR_UTF8_ERR2 Missing 2 bytes at the end of the string
+PCRE2_ERROR_UTF8_ERR3 Missing 3 bytes at the end of the string
+PCRE2_ERROR_UTF8_ERR4 Missing 4 bytes at the end of the string
+PCRE2_ERROR_UTF8_ERR5 Missing 5 bytes at the end of the string
+PCRE2_ERROR_UTF8_ERR6 2nd-byte's two top bits are not 0x80
+PCRE2_ERROR_UTF8_ERR7 3rd-byte's two top bits are not 0x80
+PCRE2_ERROR_UTF8_ERR8 4th-byte's two top bits are not 0x80
+PCRE2_ERROR_UTF8_ERR9 5th-byte's two top bits are not 0x80
+PCRE2_ERROR_UTF8_ERR10 6th-byte's two top bits are not 0x80
+PCRE2_ERROR_UTF8_ERR11 5-byte character is not permitted by RFC 3629
+PCRE2_ERROR_UTF8_ERR12 6-byte character is not permitted by RFC 3629
+PCRE2_ERROR_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted
+PCRE2_ERROR_UTF8_ERR14 3-byte character with value 0xd800-0xdfff is not permitted
+PCRE2_ERROR_UTF8_ERR15 Overlong 2-byte sequence
+PCRE2_ERROR_UTF8_ERR16 Overlong 3-byte sequence
+PCRE2_ERROR_UTF8_ERR17 Overlong 4-byte sequence
+PCRE2_ERROR_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
+PCRE2_ERROR_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
+PCRE2_ERROR_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
+PCRE2_ERROR_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
+*/
+
+for (p = string; length > 0; p++)
+ {
+ uint32_t ab, d;
+
+ c = *p;
+ length--;
+
+ if (c < 128) continue; /* ASCII character */
+
+ if (c < 0xc0) /* Isolated 10xx xxxx byte */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE2_ERROR_UTF8_ERR20;
+ }
+
+ if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE2_ERROR_UTF8_ERR21;
+ }
+
+ ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes (1-5) */
+ if (length < ab) /* Missing bytes */
+ {
+ *erroroffset = (int)(p - string);
+ switch(ab - length)
+ {
+ case 1: return PCRE2_ERROR_UTF8_ERR1;
+ case 2: return PCRE2_ERROR_UTF8_ERR2;
+ case 3: return PCRE2_ERROR_UTF8_ERR3;
+ case 4: return PCRE2_ERROR_UTF8_ERR4;
+ case 5: return PCRE2_ERROR_UTF8_ERR5;
+ }
+ }
+ length -= ab; /* Length remaining */
+
+ /* Check top bits in the second byte */
+
+ if (((d = *(++p)) & 0xc0) != 0x80)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE2_ERROR_UTF8_ERR6;
+ }
+
+ /* For each length, check that the remaining bytes start with the 0x80 bit
+ set and not the 0x40 bit. Then check for an overlong sequence, and for the
+ excluded range 0xd800 to 0xdfff. */
+
+ switch (ab)
+ {
+ /* 2-byte character. No further bytes to check for 0x80. Check first byte
+ for for xx00 000x (overlong sequence). */
+
+ case 1: if ((c & 0x3e) == 0)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE2_ERROR_UTF8_ERR15;
+ }
+ break;
+
+ /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes
+ for 1110 0000, xx0x xxxx (overlong sequence) or
+ 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */
+
+ case 2:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE2_ERROR_UTF8_ERR7;
+ }
+ if (c == 0xe0 && (d & 0x20) == 0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE2_ERROR_UTF8_ERR16;
+ }
+ if (c == 0xed && d >= 0xa0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE2_ERROR_UTF8_ERR14;
+ }
+ break;
+
+ /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
+ bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a
+ character greater than 0x0010ffff (f4 8f bf bf) */
+
+ case 3:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE2_ERROR_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE2_ERROR_UTF8_ERR8;
+ }
+ if (c == 0xf0 && (d & 0x30) == 0)
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE2_ERROR_UTF8_ERR17;
+ }
+ if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE2_ERROR_UTF8_ERR13;
+ }
+ break;
+
+ /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
+ rejected by the length test below. However, we do the appropriate tests
+ here so that overlong sequences get diagnosed, and also in case there is
+ ever an option for handling these larger code points. */
+
+ /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for
+ 1111 1000, xx00 0xxx */
+
+ case 4:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE2_ERROR_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE2_ERROR_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE2_ERROR_UTF8_ERR9;
+ }
+ if (c == 0xf8 && (d & 0x38) == 0)
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE2_ERROR_UTF8_ERR18;
+ }
+ break;
+
+ /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for
+ 1111 1100, xx00 00xx. */
+
+ case 5:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE2_ERROR_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE2_ERROR_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE2_ERROR_UTF8_ERR9;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE2_ERROR_UTF8_ERR10;
+ }
+ if (c == 0xfc && (d & 0x3c) == 0)
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE2_ERROR_UTF8_ERR19;
+ }
+ break;
+ }
+
+ /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are
+ excluded by RFC 3629. The pointer p is currently at the last byte of the
+ character. */
+
+ if (ab > 3)
+ {
+ *erroroffset = (int)(p - string) - ab;
+ return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12;
+ }
+ }
+return 0;
+
+
+/* ----------------- Check a UTF-16 string ----------------- */
+
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+
+/* There's not so much work, nor so many errors, for UTF-16.
+PCRE2_ERROR_UTF16_ERR1 Missing low surrogate at the end of the string
+PCRE2_ERROR_UTF16_ERR2 Invalid low surrogate
+PCRE2_ERROR_UTF16_ERR3 Isolated low surrogate
+*/
+
+for (p = string; length > 0; p++)
+ {
+ c = *p;
+ length--;
+
+ if ((c & 0xf800) != 0xd800)
+ {
+ /* Normal UTF-16 code point. Neither high nor low surrogate. */
+ }
+ else if ((c & 0x0400) == 0)
+ {
+ /* High surrogate. Must be a followed by a low surrogate. */
+ if (length == 0)
+ {
+ *erroroffset = p - string;
+ return PCRE2_ERROR_UTF16_ERR1;
+ }
+ p++;
+ length--;
+ if ((*p & 0xfc00) != 0xdc00)
+ {
+ *erroroffset = p - string;
+ return PCRE2_ERROR_UTF16_ERR2;
+ }
+ }
+ else
+ {
+ /* Isolated low surrogate. Always an error. */
+ *erroroffset = p - string;
+ return PCRE2_ERROR_UTF16_ERR3;
+ }
+ }
+return 0;
+
+
+
+/* ----------------- Check a UTF-32 string ----------------- */
+
+#else
+
+/* There is very little to do for a UTF-32 string.
+PCRE2_ERROR_UTF32_ERR1 Surrogate character
+PCRE2_ERROR_UTF32_ERR2 Character > 0x10ffff
+*/
+
+for (p = string; length > 0; length--, p++)
+ {
+ c = *p;
+ if ((c & 0xfffff800u) != 0xd800u)
+ {
+ /* Normal UTF-32 code point. Neither high nor low surrogate. */
+ if (c > 0x10ffffu)
+ {
+ *erroroffset = p - string;
+ return PCRE2_ERROR_UTF32_ERR2;
+ }
+ }
+ else
+ {
+ /* A surrogate */
+ *erroroffset = p - string;
+ return PCRE2_ERROR_UTF32_ERR1;
+ }
+ }
+return 0;
+#endif /* CODE_UNIT_WIDTH */
+}
+#endif /* SUPPORT_UNICODE */
+
+/* End of pcre2_valid_utf.c */
diff --git a/thirdparty/pcre2/src/pcre2_xclass.c b/thirdparty/pcre2/src/pcre2_xclass.c
new file mode 100644
index 0000000000..407d3f5b87
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_xclass.c
@@ -0,0 +1,271 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This module contains an internal function that is used to match an extended
+class. It is used by pcre2_auto_possessify() and by both pcre2_match() and
+pcre2_def_match(). */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "pcre2_internal.h"
+
+/*************************************************
+* Match character against an XCLASS *
+*************************************************/
+
+/* This function is called to match a character against an extended class that
+might contain codepoints above 255 and/or Unicode properties.
+
+Arguments:
+ c the character
+ data points to the flag code unit of the XCLASS data
+ utf TRUE if in UTF mode
+
+Returns: TRUE if character matches, else FALSE
+*/
+
+BOOL
+PRIV(xclass)(uint32_t c, PCRE2_SPTR data, BOOL utf)
+{
+PCRE2_UCHAR t;
+BOOL negated = (*data & XCL_NOT) != 0;
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */
+utf = TRUE;
+#endif
+
+/* Code points < 256 are matched against a bitmap, if one is present. If not,
+we still carry on, because there may be ranges that start below 256 in the
+additional data. */
+
+if (c < 256)
+ {
+ if ((*data & XCL_HASPROP) == 0)
+ {
+ if ((*data & XCL_MAP) == 0) return negated;
+ return (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0;
+ }
+ if ((*data & XCL_MAP) != 0 &&
+ (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0)
+ return !negated; /* char found */
+ }
+
+/* First skip the bit map if present. Then match against the list of Unicode
+properties or large chars or ranges that end with a large char. We won't ever
+encounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */
+
+if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(PCRE2_UCHAR);
+
+while ((t = *data++) != XCL_END)
+ {
+ uint32_t x, y;
+ if (t == XCL_SINGLE)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ x = *data++;
+ if (c == x) return !negated;
+ }
+ else if (t == XCL_RANGE)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ GETCHARINC(y, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ {
+ x = *data++;
+ y = *data++;
+ }
+ if (c >= x && c <= y) return !negated;
+ }
+
+#ifdef SUPPORT_UNICODE
+ else /* XCL_PROP & XCL_NOTPROP */
+ {
+ const ucd_record *prop = GET_UCD(c);
+ BOOL isprop = t == XCL_PROP;
+
+ switch(*data)
+ {
+ case PT_ANY:
+ if (isprop) return !negated;
+ break;
+
+ case PT_LAMP:
+ if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == isprop) return !negated;
+ break;
+
+ case PT_GC:
+ if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop)
+ return !negated;
+ break;
+
+ case PT_PC:
+ if ((data[1] == prop->chartype) == isprop) return !negated;
+ break;
+
+ case PT_SC:
+ if ((data[1] == prop->script) == isprop) return !negated;
+ break;
+
+ case PT_ALNUM:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop)
+ return !negated;
+ break;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (isprop) return !negated;
+ break;
+
+ default:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop)
+ return !negated;
+ break;
+ }
+ break;
+
+ case PT_WORD:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
+ == isprop)
+ return !negated;
+ break;
+
+ case PT_UCNC:
+ if (c < 0xa0)
+ {
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT) == isprop)
+ return !negated;
+ }
+ else
+ {
+ if ((c < 0xd800 || c > 0xdfff) == isprop)
+ return !negated;
+ }
+ break;
+
+ /* The following three properties can occur only in an XCLASS, as there
+ is no \p or \P coding for them. */
+
+ /* Graphic character. Implement this as not Z (space or separator) and
+ not C (other), except for Cf (format) with a few exceptions. This seems
+ to be what Perl does. The exceptional characters are:
+
+ U+061C Arabic Letter Mark
+ U+180E Mongolian Vowel Separator
+ U+2066 - U+2069 Various "isolate"s
+ */
+
+ case PT_PXGRAPH:
+ if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z &&
+ (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
+ (prop->chartype == ucp_Cf &&
+ c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))
+ )) == isprop)
+ return !negated;
+ break;
+
+ /* Printable character: same as graphic, with the addition of Zs, i.e.
+ not Zl and not Zp, and U+180E. */
+
+ case PT_PXPRINT:
+ if ((prop->chartype != ucp_Zl &&
+ prop->chartype != ucp_Zp &&
+ (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
+ (prop->chartype == ucp_Cf &&
+ c != 0x061c && (c < 0x2066 || c > 0x2069))
+ )) == isprop)
+ return !negated;
+ break;
+
+ /* Punctuation: all Unicode punctuation, plus ASCII characters that
+ Unicode treats as symbols rather than punctuation, for Perl
+ compatibility (these are $+<=>^`|~). */
+
+ case PT_PXPUNCT:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||
+ (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
+ return !negated;
+ break;
+
+ /* This should never occur, but compilers may mutter if there is no
+ default. */
+
+ default:
+ return FALSE;
+ }
+
+ data += 2;
+ }
+#else
+ (void)utf; /* Avoid compiler warning */
+#endif /* SUPPORT_UNICODE */
+ }
+
+return negated; /* char did not match */
+}
+
+/* End of pcre2_xclass.c */
diff --git a/thirdparty/pcre2/src/sljit/sljitConfig.h b/thirdparty/pcre2/src/sljit/sljitConfig.h
new file mode 100644
index 0000000000..2e70224da8
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitConfig.h
@@ -0,0 +1,145 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_CONFIG_H_
+#define _SLJIT_CONFIG_H_
+
+/* --------------------------------------------------------------------- */
+/* Custom defines */
+/* --------------------------------------------------------------------- */
+
+/* Put your custom defines here. This empty section will never change
+ which helps maintaining patches (with diff / patch utilities). */
+
+/* --------------------------------------------------------------------- */
+/* Architecture */
+/* --------------------------------------------------------------------- */
+
+/* Architecture selection. */
+/* #define SLJIT_CONFIG_X86_32 1 */
+/* #define SLJIT_CONFIG_X86_64 1 */
+/* #define SLJIT_CONFIG_ARM_V5 1 */
+/* #define SLJIT_CONFIG_ARM_V7 1 */
+/* #define SLJIT_CONFIG_ARM_THUMB2 1 */
+/* #define SLJIT_CONFIG_ARM_64 1 */
+/* #define SLJIT_CONFIG_PPC_32 1 */
+/* #define SLJIT_CONFIG_PPC_64 1 */
+/* #define SLJIT_CONFIG_MIPS_32 1 */
+/* #define SLJIT_CONFIG_MIPS_64 1 */
+/* #define SLJIT_CONFIG_SPARC_32 1 */
+/* #define SLJIT_CONFIG_TILEGX 1 */
+
+/* #define SLJIT_CONFIG_AUTO 1 */
+/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
+
+/* --------------------------------------------------------------------- */
+/* Utilities */
+/* --------------------------------------------------------------------- */
+
+/* Useful for thread-safe compiling of global functions. */
+#ifndef SLJIT_UTIL_GLOBAL_LOCK
+/* Enabled by default */
+#define SLJIT_UTIL_GLOBAL_LOCK 1
+#endif
+
+/* Implements a stack like data structure (by using mmap / VirtualAlloc). */
+#ifndef SLJIT_UTIL_STACK
+/* Enabled by default */
+#define SLJIT_UTIL_STACK 1
+#endif
+
+/* Single threaded application. Does not require any locks. */
+#ifndef SLJIT_SINGLE_THREADED
+/* Disabled by default. */
+#define SLJIT_SINGLE_THREADED 0
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Configuration */
+/* --------------------------------------------------------------------- */
+
+/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should
+ define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMCPY, and NULL. */
+#ifndef SLJIT_STD_MACROS_DEFINED
+/* Disabled by default. */
+#define SLJIT_STD_MACROS_DEFINED 0
+#endif
+
+/* Executable code allocation:
+ If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
+ define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_EXEC_OFFSET. */
+#ifndef SLJIT_EXECUTABLE_ALLOCATOR
+/* Enabled by default. */
+#define SLJIT_EXECUTABLE_ALLOCATOR 1
+
+/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
+ an allocator which does not set writable and executable
+ permission flags at the same time. The trade-of is increased
+ memory consumption and disabled dynamic code modifications. */
+#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
+/* Disabled by default. */
+#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
+#endif
+
+#endif
+
+/* Force cdecl calling convention even if a better calling
+ convention (e.g. fastcall) is supported by the C compiler.
+ If this option is enabled, C functions without
+ SLJIT_CALL can also be called from JIT code. */
+#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION
+/* Disabled by default */
+#define SLJIT_USE_CDECL_CALLING_CONVENTION 0
+#endif
+
+/* Return with error when an invalid argument is passed. */
+#ifndef SLJIT_ARGUMENT_CHECKS
+/* Disabled by default */
+#define SLJIT_ARGUMENT_CHECKS 0
+#endif
+
+/* Debug checks (assertions, etc.). */
+#ifndef SLJIT_DEBUG
+/* Enabled by default */
+#define SLJIT_DEBUG 1
+#endif
+
+/* Verbose operations. */
+#ifndef SLJIT_VERBOSE
+/* Enabled by default */
+#define SLJIT_VERBOSE 1
+#endif
+
+/*
+ SLJIT_IS_FPU_AVAILABLE
+ The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE.
+ zero value - FPU is NOT present.
+ nonzero value - FPU is present.
+*/
+
+/* For further configurations, see the beginning of sljitConfigInternal.h */
+
+#endif
diff --git a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
new file mode 100644
index 0000000000..5d461017e4
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
@@ -0,0 +1,724 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_CONFIG_INTERNAL_H_
+#define _SLJIT_CONFIG_INTERNAL_H_
+
+/*
+ SLJIT defines the following architecture dependent types and macros:
+
+ Types:
+ sljit_s8, sljit_u8 : signed and unsigned 8 bit integer type
+ sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type
+ sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type
+ sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
+ sljit_p : unsgined pointer value (usually the same as sljit_uw, but
+ some 64 bit ABIs may use 32 bit pointers)
+ sljit_f32 : 32 bit single precision floating point value
+ sljit_f64 : 64 bit double precision floating point value
+
+ Macros for feature detection (boolean):
+ SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
+ SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
+ SLJIT_LITTLE_ENDIAN : little endian architecture
+ SLJIT_BIG_ENDIAN : big endian architecture
+ SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)
+ SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information
+
+ Constants:
+ SLJIT_NUMBER_OF_REGISTERS : number of available registers
+ SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers
+ SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers
+ SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers
+ SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers
+ SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers
+ SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
+ SLJIT_F32_SHIFT : the shift required to apply when accessing
+ a single precision floating point array by index
+ SLJIT_F64_SHIFT : the shift required to apply when accessing
+ a double precision floating point array by index
+ SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
+ SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
+
+ Other macros:
+ SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
+ SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
+*/
+
+/*****************/
+/* Sanity check. */
+/*****************/
+
+#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
+ || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
+#error "An architecture must be selected"
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
+ + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ + (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
+#error "Multiple architectures are selected"
+#endif
+
+/********************************************************/
+/* Automatic CPU detection (requires compiler support). */
+/********************************************************/
+
+#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
+
+#ifndef _WIN32
+
+#if defined(__i386__) || defined(__i386)
+#define SLJIT_CONFIG_X86_32 1
+#elif defined(__x86_64__)
+#define SLJIT_CONFIG_X86_64 1
+#elif defined(__arm__) || defined(__ARM__)
+#ifdef __thumb2__
+#define SLJIT_CONFIG_ARM_THUMB2 1
+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)
+#define SLJIT_CONFIG_ARM_V7 1
+#else
+#define SLJIT_CONFIG_ARM_V5 1
+#endif
+#elif defined (__aarch64__)
+#define SLJIT_CONFIG_ARM_64 1
+#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__))
+#define SLJIT_CONFIG_PPC_64 1
+#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
+#define SLJIT_CONFIG_PPC_32 1
+#elif defined(__mips__) && !defined(_LP64)
+#define SLJIT_CONFIG_MIPS_32 1
+#elif defined(__mips64)
+#define SLJIT_CONFIG_MIPS_64 1
+#elif defined(__sparc__) || defined(__sparc)
+#define SLJIT_CONFIG_SPARC_32 1
+#elif defined(__tilegx__)
+#define SLJIT_CONFIG_TILEGX 1
+#else
+/* Unsupported architecture */
+#define SLJIT_CONFIG_UNSUPPORTED 1
+#endif
+
+#else /* !_WIN32 */
+
+#if defined(_M_X64) || defined(__x86_64__)
+#define SLJIT_CONFIG_X86_64 1
+#elif defined(_ARM_)
+#define SLJIT_CONFIG_ARM_V5 1
+#else
+#define SLJIT_CONFIG_X86_32 1
+#endif
+
+#endif /* !WIN32 */
+#endif /* SLJIT_CONFIG_AUTO */
+
+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+#undef SLJIT_EXECUTABLE_ALLOCATOR
+#endif
+
+/******************************/
+/* CPU family type detection. */
+/******************************/
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+#define SLJIT_CONFIG_ARM_32 1
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+#define SLJIT_CONFIG_X86 1
+#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
+#define SLJIT_CONFIG_ARM 1
+#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_CONFIG_PPC 1
+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+#define SLJIT_CONFIG_MIPS 1
+#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) || (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)
+#define SLJIT_CONFIG_SPARC 1
+#endif
+
+/**********************************/
+/* External function definitions. */
+/**********************************/
+
+/* General macros:
+ Note: SLJIT is designed to be independent from them as possible.
+
+ In release mode (SLJIT_DEBUG is not defined) only the following
+ external functions are needed:
+*/
+
+#ifndef SLJIT_MALLOC
+#define SLJIT_MALLOC(size, allocator_data) malloc(size)
+#endif
+
+#ifndef SLJIT_FREE
+#define SLJIT_FREE(ptr, allocator_data) free(ptr)
+#endif
+
+#ifndef SLJIT_MEMCPY
+#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)
+#endif
+
+#ifndef SLJIT_ZEROMEM
+#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
+#endif
+
+/***************************/
+/* Compiler helper macros. */
+/***************************/
+
+#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)
+
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+#define SLJIT_LIKELY(x) __builtin_expect((x), 1)
+#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0)
+#else
+#define SLJIT_LIKELY(x) (x)
+#define SLJIT_UNLIKELY(x) (x)
+#endif
+
+#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */
+
+#ifndef SLJIT_INLINE
+/* Inline functions. Some old compilers do not support them. */
+#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510
+#define SLJIT_INLINE
+#else
+#define SLJIT_INLINE __inline
+#endif
+#endif /* !SLJIT_INLINE */
+
+#ifndef SLJIT_NOINLINE
+/* Not inline functions. */
+#if defined(__GNUC__)
+#define SLJIT_NOINLINE __attribute__ ((noinline))
+#else
+#define SLJIT_NOINLINE
+#endif
+#endif /* !SLJIT_INLINE */
+
+#ifndef SLJIT_UNUSED_ARG
+/* Unused arguments. */
+#define SLJIT_UNUSED_ARG(arg) (void)arg
+#endif
+
+/*********************************/
+/* Type of public API functions. */
+/*********************************/
+
+#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
+/* Static ABI functions. For all-in-one programs. */
+
+#if defined(__GNUC__)
+/* Disable unused warnings in gcc. */
+#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused))
+#else
+#define SLJIT_API_FUNC_ATTRIBUTE static
+#endif
+
+#else
+#define SLJIT_API_FUNC_ATTRIBUTE
+#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
+
+/****************************/
+/* Instruction cache flush. */
+/****************************/
+
+#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin)
+#if __has_builtin(__builtin___clear_cache)
+
+#define SLJIT_CACHE_FLUSH(from, to) \
+ __builtin___clear_cache((char*)from, (char*)to)
+
+#endif /* __has_builtin(__builtin___clear_cache) */
+#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */
+
+#ifndef SLJIT_CACHE_FLUSH
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+/* Not required to implement on archs with unified caches. */
+#define SLJIT_CACHE_FLUSH(from, to)
+
+#elif defined __APPLE__
+
+/* Supported by all macs since Mac OS 10.5.
+ However, it does not work on non-jailbroken iOS devices,
+ although the compilation is successful. */
+
+#define SLJIT_CACHE_FLUSH(from, to) \
+ sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from))
+
+#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
+
+#define SLJIT_CACHE_FLUSH(from, to) \
+ __builtin___clear_cache((char*)from, (char*)to)
+
+#elif defined __ANDROID__
+
+/* Android lacks __clear_cache; instead, cacheflush should be used. */
+
+#define SLJIT_CACHE_FLUSH(from, to) \
+ cacheflush((long)(from), (long)(to), 0)
+
+#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+
+/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+ ppc_cache_flush((from), (to))
+#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
+
+#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+
+/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+ sparc_cache_flush((from), (to))
+#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
+
+#else
+
+/* Calls __ARM_NR_cacheflush on ARM-Linux. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+ __clear_cache((char*)(from), (char*)(to))
+
+#endif
+
+#endif /* !SLJIT_CACHE_FLUSH */
+
+/******************************************************/
+/* Integer and floating point type definitions. */
+/******************************************************/
+
+/* 8 bit byte type. */
+typedef unsigned char sljit_u8;
+typedef signed char sljit_s8;
+
+/* 16 bit half-word type. */
+typedef unsigned short int sljit_u16;
+typedef signed short int sljit_s16;
+
+/* 32 bit integer type. */
+typedef unsigned int sljit_u32;
+typedef signed int sljit_s32;
+
+/* Machine word type. Enough for storing a pointer.
+ 32 bit for 32 bit machines.
+ 64 bit for 64 bit machines. */
+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+/* Just to have something. */
+#define SLJIT_WORD_SHIFT 0
+typedef unsigned long int sljit_uw;
+typedef long int sljit_sw;
+#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+#define SLJIT_32BIT_ARCHITECTURE 1
+#define SLJIT_WORD_SHIFT 2
+typedef unsigned int sljit_uw;
+typedef int sljit_sw;
+#else
+#define SLJIT_64BIT_ARCHITECTURE 1
+#define SLJIT_WORD_SHIFT 3
+#ifdef _WIN32
+typedef unsigned __int64 sljit_uw;
+typedef __int64 sljit_sw;
+#else
+typedef unsigned long int sljit_uw;
+typedef long int sljit_sw;
+#endif
+#endif
+
+typedef sljit_uw sljit_p;
+
+/* Floating point types. */
+typedef float sljit_f32;
+typedef double sljit_f64;
+
+/* Shift for pointer sized data. */
+#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT
+
+/* Shift for double precision sized data. */
+#define SLJIT_F32_SHIFT 2
+#define SLJIT_F64_SHIFT 3
+
+#ifndef SLJIT_W
+
+/* Defining long constants. */
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#define SLJIT_W(w) (w##ll)
+#else
+#define SLJIT_W(w) (w)
+#endif
+
+#endif /* !SLJIT_W */
+
+/*************************/
+/* Endianness detection. */
+/*************************/
+
+#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
+
+/* These macros are mostly useful for the applications. */
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+
+#ifdef __LITTLE_ENDIAN__
+#define SLJIT_LITTLE_ENDIAN 1
+#else
+#define SLJIT_BIG_ENDIAN 1
+#endif
+
+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+
+#ifdef __MIPSEL__
+#define SLJIT_LITTLE_ENDIAN 1
+#else
+#define SLJIT_BIG_ENDIAN 1
+#endif
+
+#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+
+#define SLJIT_BIG_ENDIAN 1
+
+#else
+#define SLJIT_LITTLE_ENDIAN 1
+#endif
+
+#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */
+
+/* Sanity check. */
+#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#error "Exactly one endianness must be selected"
+#endif
+
+#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#error "Exactly one endianness must be selected"
+#endif
+
+#ifndef SLJIT_UNALIGNED
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_UNALIGNED 1
+#endif
+
+#endif /* !SLJIT_UNALIGNED */
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+/* Auto detect SSE2 support using CPUID.
+ On 64 bit x86 cpus, sse2 must be present. */
+#define SLJIT_DETECT_SSE2 1
+#endif
+
+/*****************************************************************************************/
+/* Calling convention of functions generated by SLJIT or called from the generated code. */
+/*****************************************************************************************/
+
+#ifndef SLJIT_CALL
+
+#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
+
+/* Force cdecl. */
+#define SLJIT_CALL
+
+#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+
+#if defined(__GNUC__) && !defined(__APPLE__)
+
+#define SLJIT_CALL __attribute__ ((fastcall))
+#define SLJIT_X86_32_FASTCALL 1
+
+#elif defined(_MSC_VER)
+
+#define SLJIT_CALL __fastcall
+#define SLJIT_X86_32_FASTCALL 1
+
+#elif defined(__BORLANDC__)
+
+#define SLJIT_CALL __msfastcall
+#define SLJIT_X86_32_FASTCALL 1
+
+#else /* Unknown compiler. */
+
+/* The cdecl attribute is the default. */
+#define SLJIT_CALL
+
+#endif
+
+#else /* Non x86-32 architectures. */
+
+#define SLJIT_CALL
+
+#endif /* SLJIT_CONFIG_X86_32 */
+
+#endif /* !SLJIT_CALL */
+
+#ifndef SLJIT_INDIRECT_CALL
+#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \
+ || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)
+/* It seems certain ppc compilers use an indirect addressing for functions
+ which makes things complicated. */
+#define SLJIT_INDIRECT_CALL 1
+#endif
+#endif /* SLJIT_INDIRECT_CALL */
+
+/* The offset which needs to be substracted from the return address to
+determine the next executed instruction after return. */
+#ifndef SLJIT_RETURN_ADDRESS_OFFSET
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+#define SLJIT_RETURN_ADDRESS_OFFSET 8
+#else
+#define SLJIT_RETURN_ADDRESS_OFFSET 0
+#endif
+#endif /* SLJIT_RETURN_ADDRESS_OFFSET */
+
+/***************************************************/
+/* Functions of the built-in executable allocator. */
+/***************************************************/
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
+#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
+#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
+
+#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
+SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
+#define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr)
+#else
+#define SLJIT_EXEC_OFFSET(ptr) 0
+#endif
+
+#endif
+
+/**********************************************/
+/* Registers and locals offset determination. */
+/**********************************************/
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+
+#define SLJIT_NUMBER_OF_REGISTERS 10
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+#define SLJIT_LOCALS_OFFSET_BASE ((2 + 4) * sizeof(sljit_sw))
+#else
+/* Maximum 3 arguments are passed on the stack, +1 for double alignment. */
+#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1 + 4) * sizeof(sljit_sw))
+#endif /* SLJIT_X86_32_FASTCALL */
+
+#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+#ifndef _WIN64
+#define SLJIT_NUMBER_OF_REGISTERS 12
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
+#define SLJIT_LOCALS_OFFSET_BASE (sizeof(sljit_sw))
+#else
+#define SLJIT_NUMBER_OF_REGISTERS 12
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
+#define SLJIT_LOCALS_OFFSET_BASE ((4 + 2) * sizeof(sljit_sw))
+#endif /* _WIN64 */
+
+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+
+#define SLJIT_NUMBER_OF_REGISTERS 11
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
+#define SLJIT_LOCALS_OFFSET_BASE 0
+
+#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+
+#define SLJIT_NUMBER_OF_REGISTERS 11
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
+#define SLJIT_LOCALS_OFFSET_BASE 0
+
+#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
+
+#define SLJIT_NUMBER_OF_REGISTERS 25
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
+#define SLJIT_LOCALS_OFFSET_BASE (2 * sizeof(sljit_sw))
+
+#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+
+#define SLJIT_NUMBER_OF_REGISTERS 22
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
+#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * sizeof(sljit_sw))
+#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+/* Add +1 for double alignment. */
+#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * sizeof(sljit_sw))
+#else
+#define SLJIT_LOCALS_OFFSET_BASE (3 * sizeof(sljit_sw))
+#endif /* SLJIT_CONFIG_PPC_64 || _AIX */
+
+#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+
+#define SLJIT_NUMBER_OF_REGISTERS 17
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define SLJIT_LOCALS_OFFSET_BASE (4 * sizeof(sljit_sw))
+#else
+#define SLJIT_LOCALS_OFFSET_BASE 0
+#endif
+
+#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
+
+#define SLJIT_NUMBER_OF_REGISTERS 18
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 14
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+/* Add +1 for double alignment. */
+#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
+#endif
+
+#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+
+#define SLJIT_NUMBER_OF_REGISTERS 10
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
+#define SLJIT_LOCALS_OFFSET_BASE 0
+
+#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+
+#define SLJIT_NUMBER_OF_REGISTERS 0
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0
+#define SLJIT_LOCALS_OFFSET_BASE 0
+
+#endif
+
+#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE)
+
+#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \
+ (SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS)
+
+#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 6
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && (defined _WIN64)
+#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 1
+#else
+#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
+#endif
+
+#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \
+ (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)
+
+/*************************************/
+/* Debug and verbose related macros. */
+/*************************************/
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+#include <stdio.h>
+#endif
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+
+#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP)
+
+/* SLJIT_HALT_PROCESS must halt the process. */
+#ifndef SLJIT_HALT_PROCESS
+#include <stdlib.h>
+
+#define SLJIT_HALT_PROCESS() \
+ abort();
+#endif /* !SLJIT_HALT_PROCESS */
+
+#include <stdio.h>
+
+#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */
+
+/* Feel free to redefine these two macros. */
+#ifndef SLJIT_ASSERT
+
+#define SLJIT_ASSERT(x) \
+ do { \
+ if (SLJIT_UNLIKELY(!(x))) { \
+ printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \
+ SLJIT_HALT_PROCESS(); \
+ } \
+ } while (0)
+
+#endif /* !SLJIT_ASSERT */
+
+#ifndef SLJIT_ASSERT_STOP
+
+#define SLJIT_ASSERT_STOP() \
+ do { \
+ printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \
+ SLJIT_HALT_PROCESS(); \
+ } while (0)
+
+#endif /* !SLJIT_ASSERT_STOP */
+
+#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
+
+/* Forcing empty, but valid statements. */
+#undef SLJIT_ASSERT
+#undef SLJIT_ASSERT_STOP
+
+#define SLJIT_ASSERT(x) \
+ do { } while (0)
+#define SLJIT_ASSERT_STOP() \
+ do { } while (0)
+
+#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
+
+#ifndef SLJIT_COMPILE_ASSERT
+
+/* Should be improved eventually. */
+#define SLJIT_COMPILE_ASSERT(x, description) \
+ SLJIT_ASSERT(x)
+
+#endif /* !SLJIT_COMPILE_ASSERT */
+
+#endif
diff --git a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
new file mode 100644
index 0000000000..9f88f990b0
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
@@ -0,0 +1,312 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ This file contains a simple executable memory allocator
+
+ It is assumed, that executable code blocks are usually medium (or sometimes
+ large) memory blocks, and the allocator is not too frequently called (less
+ optimized than other allocators). Thus, using it as a generic allocator is
+ not suggested.
+
+ How does it work:
+ Memory is allocated in continuous memory areas called chunks by alloc_chunk()
+ Chunk format:
+ [ block ][ block ] ... [ block ][ block terminator ]
+
+ All blocks and the block terminator is started with block_header. The block
+ header contains the size of the previous and the next block. These sizes
+ can also contain special values.
+ Block size:
+ 0 - The block is a free_block, with a different size member.
+ 1 - The block is a block terminator.
+ n - The block is used at the moment, and the value contains its size.
+ Previous block size:
+ 0 - This is the first block of the memory chunk.
+ n - The size of the previous block.
+
+ Using these size values we can go forward or backward on the block chain.
+ The unused blocks are stored in a chain list pointed by free_blocks. This
+ list is useful if we need to find a suitable memory area when the allocator
+ is called.
+
+ When a block is freed, the new free block is connected to its adjacent free
+ blocks if possible.
+
+ [ free block ][ used block ][ free block ]
+ and "used block" is freed, the three blocks are connected together:
+ [ one big free block ]
+*/
+
+/* --------------------------------------------------------------------- */
+/* System (OS) functions */
+/* --------------------------------------------------------------------- */
+
+/* 64 KByte. */
+#define CHUNK_SIZE 0x10000
+
+/*
+ alloc_chunk / free_chunk :
+ * allocate executable system memory chunks
+ * the size is always divisible by CHUNK_SIZE
+ allocator_grab_lock / allocator_release_lock :
+ * make the allocator thread safe
+ * can be empty if the OS (or the application) does not support threading
+ * only the allocator requires this lock, sljit is fully thread safe
+ as it only uses local variables
+*/
+
+#ifdef _WIN32
+
+static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
+{
+ return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+}
+
+static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
+{
+ SLJIT_UNUSED_ARG(size);
+ VirtualFree(chunk, 0, MEM_RELEASE);
+}
+
+#else
+
+static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
+{
+ void *retval;
+
+#ifdef MAP_ANON
+ retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
+#else
+ if (dev_zero < 0) {
+ if (open_dev_zero())
+ return NULL;
+ }
+ retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0);
+#endif
+
+ return (retval != MAP_FAILED) ? retval : NULL;
+}
+
+static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
+{
+ munmap(chunk, size);
+}
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Common functions */
+/* --------------------------------------------------------------------- */
+
+#define CHUNK_MASK (~(CHUNK_SIZE - 1))
+
+struct block_header {
+ sljit_uw size;
+ sljit_uw prev_size;
+};
+
+struct free_block {
+ struct block_header header;
+ struct free_block *next;
+ struct free_block *prev;
+ sljit_uw size;
+};
+
+#define AS_BLOCK_HEADER(base, offset) \
+ ((struct block_header*)(((sljit_u8*)base) + offset))
+#define AS_FREE_BLOCK(base, offset) \
+ ((struct free_block*)(((sljit_u8*)base) + offset))
+#define MEM_START(base) ((void*)(((sljit_u8*)base) + sizeof(struct block_header)))
+#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7)
+
+static struct free_block* free_blocks;
+static sljit_uw allocated_size;
+static sljit_uw total_size;
+
+static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
+{
+ free_block->header.size = 0;
+ free_block->size = size;
+
+ free_block->next = free_blocks;
+ free_block->prev = NULL;
+ if (free_blocks)
+ free_blocks->prev = free_block;
+ free_blocks = free_block;
+}
+
+static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
+{
+ if (free_block->next)
+ free_block->next->prev = free_block->prev;
+
+ if (free_block->prev)
+ free_block->prev->next = free_block->next;
+ else {
+ SLJIT_ASSERT(free_blocks == free_block);
+ free_blocks = free_block->next;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+ struct block_header *header;
+ struct block_header *next_header;
+ struct free_block *free_block;
+ sljit_uw chunk_size;
+
+ allocator_grab_lock();
+ if (size < (64 - sizeof(struct block_header)))
+ size = (64 - sizeof(struct block_header));
+ size = ALIGN_SIZE(size);
+
+ free_block = free_blocks;
+ while (free_block) {
+ if (free_block->size >= size) {
+ chunk_size = free_block->size;
+ if (chunk_size > size + 64) {
+ /* We just cut a block from the end of the free block. */
+ chunk_size -= size;
+ free_block->size = chunk_size;
+ header = AS_BLOCK_HEADER(free_block, chunk_size);
+ header->prev_size = chunk_size;
+ AS_BLOCK_HEADER(header, size)->prev_size = size;
+ }
+ else {
+ sljit_remove_free_block(free_block);
+ header = (struct block_header*)free_block;
+ size = chunk_size;
+ }
+ allocated_size += size;
+ header->size = size;
+ allocator_release_lock();
+ return MEM_START(header);
+ }
+ free_block = free_block->next;
+ }
+
+ chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
+ header = (struct block_header*)alloc_chunk(chunk_size);
+ if (!header) {
+ allocator_release_lock();
+ return NULL;
+ }
+
+ chunk_size -= sizeof(struct block_header);
+ total_size += chunk_size;
+
+ header->prev_size = 0;
+ if (chunk_size > size + 64) {
+ /* Cut the allocated space into a free and a used block. */
+ allocated_size += size;
+ header->size = size;
+ chunk_size -= size;
+
+ free_block = AS_FREE_BLOCK(header, size);
+ free_block->header.prev_size = size;
+ sljit_insert_free_block(free_block, chunk_size);
+ next_header = AS_BLOCK_HEADER(free_block, chunk_size);
+ }
+ else {
+ /* All space belongs to this allocation. */
+ allocated_size += chunk_size;
+ header->size = chunk_size;
+ next_header = AS_BLOCK_HEADER(header, chunk_size);
+ }
+ next_header->size = 1;
+ next_header->prev_size = chunk_size;
+ allocator_release_lock();
+ return MEM_START(header);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+ struct block_header *header;
+ struct free_block* free_block;
+
+ allocator_grab_lock();
+ header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
+ allocated_size -= header->size;
+
+ /* Connecting free blocks together if possible. */
+
+ /* If header->prev_size == 0, free_block will equal to header.
+ In this case, free_block->header.size will be > 0. */
+ free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size);
+ if (SLJIT_UNLIKELY(!free_block->header.size)) {
+ free_block->size += header->size;
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ header->prev_size = free_block->size;
+ }
+ else {
+ free_block = (struct free_block*)header;
+ sljit_insert_free_block(free_block, header->size);
+ }
+
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ if (SLJIT_UNLIKELY(!header->size)) {
+ free_block->size += ((struct free_block*)header)->size;
+ sljit_remove_free_block((struct free_block*)header);
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ header->prev_size = free_block->size;
+ }
+
+ /* The whole chunk is free. */
+ if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
+ /* If this block is freed, we still have (allocated_size / 2) free space. */
+ if (total_size - free_block->size > (allocated_size * 3 / 2)) {
+ total_size -= free_block->size;
+ sljit_remove_free_block(free_block);
+ free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ }
+ }
+
+ allocator_release_lock();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
+{
+ struct free_block* free_block;
+ struct free_block* next_free_block;
+
+ allocator_grab_lock();
+
+ free_block = free_blocks;
+ while (free_block) {
+ next_free_block = free_block->next;
+ if (!free_block->header.prev_size &&
+ AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
+ total_size -= free_block->size;
+ sljit_remove_free_block(free_block);
+ free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ }
+ free_block = next_free_block;
+ }
+
+ SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
+ allocator_release_lock();
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitLir.c b/thirdparty/pcre2/src/sljit/sljitLir.c
new file mode 100644
index 0000000000..0b39ec90a9
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitLir.c
@@ -0,0 +1,2067 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sljitLir.h"
+
+#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
+
+/* These libraries are needed for the macros below. */
+#include <stdlib.h>
+#include <string.h>
+
+#endif /* SLJIT_STD_MACROS_DEFINED */
+
+#define CHECK_ERROR() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return compiler->error; \
+ } while (0)
+
+#define CHECK_ERROR_PTR() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return NULL; \
+ } while (0)
+
+#define FAIL_IF(expr) \
+ do { \
+ if (SLJIT_UNLIKELY(expr)) \
+ return compiler->error; \
+ } while (0)
+
+#define PTR_FAIL_IF(expr) \
+ do { \
+ if (SLJIT_UNLIKELY(expr)) \
+ return NULL; \
+ } while (0)
+
+#define FAIL_IF_NULL(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_ALLOC_FAILED; \
+ return SLJIT_ERR_ALLOC_FAILED; \
+ } \
+ } while (0)
+
+#define PTR_FAIL_IF_NULL(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_ALLOC_FAILED; \
+ return NULL; \
+ } \
+ } while (0)
+
+#define PTR_FAIL_WITH_EXEC_IF(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
+ return NULL; \
+ } \
+ } while (0)
+
+#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+
+#define GET_OPCODE(op) \
+ ((op) & ~(SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+
+#define GET_FLAGS(op) \
+ ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))
+
+#define GET_ALL_FLAGS(op) \
+ ((op) & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+
+#define TYPE_CAST_NEEDED(op) \
+ (((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16) || ((op) >= SLJIT_MOVU_U8 && (op) <= SLJIT_MOVU_S16))
+
+#define BUF_SIZE 4096
+
+#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
+#define ABUF_SIZE 2048
+#else
+#define ABUF_SIZE 4096
+#endif
+
+/* Parameter parsing. */
+#define REG_MASK 0x3f
+#define OFFS_REG(reg) (((reg) >> 8) & REG_MASK)
+#define OFFS_REG_MASK (REG_MASK << 8)
+#define TO_OFFS_REG(reg) ((reg) << 8)
+/* When reg cannot be unused. */
+#define FAST_IS_REG(reg) ((reg) <= REG_MASK)
+/* When reg can be unused. */
+#define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK)
+
+/* Jump flags. */
+#define JUMP_LABEL 0x1
+#define JUMP_ADDR 0x2
+/* SLJIT_REWRITABLE_JUMP is 0x1000. */
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+# define PATCH_MB 0x4
+# define PATCH_MW 0x8
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+# define PATCH_MD 0x10
+#endif
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+# define IS_BL 0x4
+# define PATCH_B 0x8
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+# define CPOOL_SIZE 512
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+# define IS_COND 0x04
+# define IS_BL 0x08
+ /* conditional + imm8 */
+# define PATCH_TYPE1 0x10
+ /* conditional + imm20 */
+# define PATCH_TYPE2 0x20
+ /* IT + imm24 */
+# define PATCH_TYPE3 0x30
+ /* imm11 */
+# define PATCH_TYPE4 0x40
+ /* imm24 */
+# define PATCH_TYPE5 0x50
+ /* BL + imm24 */
+# define PATCH_BL 0x60
+ /* 0xf00 cc code for branches */
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
+# define IS_COND 0x004
+# define IS_CBZ 0x008
+# define IS_BL 0x010
+# define PATCH_B 0x020
+# define PATCH_COND 0x040
+# define PATCH_ABS48 0x080
+# define PATCH_ABS64 0x100
+#endif
+
+#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+# define IS_COND 0x004
+# define IS_CALL 0x008
+# define PATCH_B 0x010
+# define PATCH_ABS_B 0x020
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+# define PATCH_ABS32 0x040
+# define PATCH_ABS48 0x080
+#endif
+# define REMOVE_COND 0x100
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+# define IS_MOVABLE 0x004
+# define IS_JAL 0x008
+# define IS_CALL 0x010
+# define IS_BIT26_COND 0x020
+# define IS_BIT16_COND 0x040
+
+# define IS_COND (IS_BIT26_COND | IS_BIT16_COND)
+
+# define PATCH_B 0x080
+# define PATCH_J 0x100
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+# define PATCH_ABS32 0x200
+# define PATCH_ABS48 0x400
+#endif
+
+ /* instruction types */
+# define MOVABLE_INS 0
+ /* 1 - 31 last destination register */
+ /* no destination (i.e: store) */
+# define UNMOVABLE_INS 32
+ /* FPU status register */
+# define FCSR_FCC 33
+#endif
+
+#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+# define IS_JAL 0x04
+# define IS_COND 0x08
+
+# define PATCH_B 0x10
+# define PATCH_J 0x20
+#endif
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+# define IS_MOVABLE 0x04
+# define IS_COND 0x08
+# define IS_CALL 0x10
+
+# define PATCH_B 0x20
+# define PATCH_CALL 0x40
+
+ /* instruction types */
+# define MOVABLE_INS 0
+ /* 1 - 31 last destination register */
+ /* no destination (i.e: store) */
+# define UNMOVABLE_INS 32
+
+# define DST_INS_MASK 0xff
+
+ /* ICC_SET is the same as SET_FLAGS. */
+# define ICC_IS_SET (1 << 23)
+# define FCC_IS_SET (1 << 24)
+#endif
+
+/* Stack management. */
+
+#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
+ (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \
+ (saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? saveds : SLJIT_NUMBER_OF_SAVED_REGISTERS) + \
+ extra) * sizeof(sljit_sw))
+
+#define ADJUST_LOCAL_OFFSET(p, i) \
+ if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
+ (i) += SLJIT_LOCALS_OFFSET;
+
+#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
+
+/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
+#include "sljitUtils.c"
+
+#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
+#include "sljitProtExecAllocator.c"
+#else
+#include "sljitExecAllocator.c"
+#endif
+
+#endif
+
+#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
+#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
+#else
+#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
+#endif
+
+/* Argument checking features. */
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+
+/* Returns with error when an invalid argument is passed. */
+
+#define CHECK_ARGUMENT(x) \
+ do { \
+ if (SLJIT_UNLIKELY(!(x))) \
+ return 1; \
+ } while (0)
+
+#define CHECK_RETURN_TYPE sljit_s32
+#define CHECK_RETURN_OK return 0
+
+#define CHECK(x) \
+ do { \
+ if (SLJIT_UNLIKELY(x)) { \
+ compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
+ return SLJIT_ERR_BAD_ARGUMENT; \
+ } \
+ } while (0)
+
+#define CHECK_PTR(x) \
+ do { \
+ if (SLJIT_UNLIKELY(x)) { \
+ compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
+ return NULL; \
+ } \
+ } while (0)
+
+#define CHECK_REG_INDEX(x) \
+ do { \
+ if (SLJIT_UNLIKELY(x)) { \
+ return -2; \
+ } \
+ } while (0)
+
+#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
+
+/* Assertion failure occures if an invalid argument is passed. */
+#undef SLJIT_ARGUMENT_CHECKS
+#define SLJIT_ARGUMENT_CHECKS 1
+
+#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)
+#define CHECK_RETURN_TYPE void
+#define CHECK_RETURN_OK return
+#define CHECK(x) x
+#define CHECK_PTR(x) x
+#define CHECK_REG_INDEX(x) x
+
+#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+
+/* Arguments are not checked. */
+#define CHECK_RETURN_TYPE void
+#define CHECK_RETURN_OK return
+#define CHECK(x) x
+#define CHECK_PTR(x) x
+#define CHECK_REG_INDEX(x) x
+
+#else
+
+/* Arguments are not checked. */
+#define CHECK(x)
+#define CHECK_PTR(x)
+#define CHECK_REG_INDEX(x)
+
+#endif /* SLJIT_ARGUMENT_CHECKS */
+
+/* --------------------------------------------------------------------- */
+/* Public functions */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+#define SLJIT_NEEDS_COMPILER_INIT 1
+static sljit_s32 compiler_initialized = 0;
+/* A thread safe initialization. */
+static void init_compiler(void);
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
+{
+ struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
+ if (!compiler)
+ return NULL;
+ SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
+
+ SLJIT_COMPILE_ASSERT(
+ sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1
+ && sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2
+ && sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4
+ && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8)
+ && sizeof(sljit_p) <= sizeof(sljit_sw)
+ && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
+ && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),
+ invalid_integer_types);
+ SLJIT_COMPILE_ASSERT(SLJIT_I32_OP == SLJIT_F32_OP,
+ int_op_and_single_op_must_be_the_same);
+ SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_F32_OP,
+ rewritable_jump_and_single_op_must_not_be_the_same);
+
+ /* Only the non-zero members must be set. */
+ compiler->error = SLJIT_SUCCESS;
+
+ compiler->allocator_data = allocator_data;
+ compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
+ compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
+
+ if (!compiler->buf || !compiler->abuf) {
+ if (compiler->buf)
+ SLJIT_FREE(compiler->buf, allocator_data);
+ if (compiler->abuf)
+ SLJIT_FREE(compiler->abuf, allocator_data);
+ SLJIT_FREE(compiler, allocator_data);
+ return NULL;
+ }
+
+ compiler->buf->next = NULL;
+ compiler->buf->used_size = 0;
+ compiler->abuf->next = NULL;
+ compiler->abuf->used_size = 0;
+
+ compiler->scratches = -1;
+ compiler->saveds = -1;
+ compiler->fscratches = -1;
+ compiler->fsaveds = -1;
+ compiler->local_size = -1;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->args = -1;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)
+ + CPOOL_SIZE * sizeof(sljit_u8), allocator_data);
+ if (!compiler->cpool) {
+ SLJIT_FREE(compiler->buf, allocator_data);
+ SLJIT_FREE(compiler->abuf, allocator_data);
+ SLJIT_FREE(compiler, allocator_data);
+ return NULL;
+ }
+ compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);
+ compiler->cpool_diff = 0xffffffff;
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+ compiler->delay_slot = UNMOVABLE_INS;
+#endif
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ compiler->delay_slot = UNMOVABLE_INS;
+#endif
+
+#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
+ if (!compiler_initialized) {
+ init_compiler();
+ compiler_initialized = 1;
+ }
+#endif
+
+ return compiler;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ struct sljit_memory_fragment *curr;
+ void *allocator_data = compiler->allocator_data;
+ SLJIT_UNUSED_ARG(allocator_data);
+
+ buf = compiler->buf;
+ while (buf) {
+ curr = buf;
+ buf = buf->next;
+ SLJIT_FREE(curr, allocator_data);
+ }
+
+ buf = compiler->abuf;
+ while (buf) {
+ curr = buf;
+ buf = buf->next;
+ SLJIT_FREE(curr, allocator_data);
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ SLJIT_FREE(compiler->cpool, allocator_data);
+#endif
+ SLJIT_FREE(compiler, allocator_data);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
+{
+ if (compiler->error == SLJIT_SUCCESS)
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+}
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ /* Remove thumb mode flag. */
+ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
+}
+#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ /* Resolve indirection. */
+ code = (void*)(*(sljit_uw*)code);
+ SLJIT_FREE_EXEC(code);
+}
+#else
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ SLJIT_FREE_EXEC(code);
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
+{
+ if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
+ jump->flags &= ~JUMP_ADDR;
+ jump->flags |= JUMP_LABEL;
+ jump->u.label = label;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
+{
+ if (SLJIT_LIKELY(!!jump)) {
+ jump->flags &= ~JUMP_LABEL;
+ jump->flags |= JUMP_ADDR;
+ jump->u.target = target;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Private functions */
+/* --------------------------------------------------------------------- */
+
+static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)
+{
+ sljit_u8 *ret;
+ struct sljit_memory_fragment *new_frag;
+
+ SLJIT_ASSERT(size <= 256);
+ if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
+ ret = compiler->buf->memory + compiler->buf->used_size;
+ compiler->buf->used_size += size;
+ return ret;
+ }
+ new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);
+ PTR_FAIL_IF_NULL(new_frag);
+ new_frag->next = compiler->buf;
+ compiler->buf = new_frag;
+ new_frag->used_size = size;
+ return new_frag->memory;
+}
+
+static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)
+{
+ sljit_u8 *ret;
+ struct sljit_memory_fragment *new_frag;
+
+ SLJIT_ASSERT(size <= 256);
+ if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
+ ret = compiler->abuf->memory + compiler->abuf->used_size;
+ compiler->abuf->used_size += size;
+ return ret;
+ }
+ new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);
+ PTR_FAIL_IF_NULL(new_frag);
+ new_frag->next = compiler->abuf;
+ compiler->abuf = new_frag;
+ new_frag->used_size = size;
+ return new_frag->memory;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
+{
+ CHECK_ERROR_PTR();
+
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+ if (size <= 0 || size > 128)
+ return NULL;
+ size = (size + 7) & ~7;
+#else
+ if (size <= 0 || size > 64)
+ return NULL;
+ size = (size + 3) & ~3;
+#endif
+ return ensure_abuf(compiler, size);
+}
+
+static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf = compiler->buf;
+ struct sljit_memory_fragment *prev = NULL;
+ struct sljit_memory_fragment *tmp;
+
+ do {
+ tmp = buf->next;
+ buf->next = prev;
+ prev = buf;
+ buf = tmp;
+ } while (buf != NULL);
+
+ compiler->buf = prev;
+}
+
+static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(local_size);
+
+ compiler->options = options;
+ compiler->scratches = scratches;
+ compiler->saveds = saveds;
+ compiler->fscratches = fscratches;
+ compiler->fsaveds = fsaveds;
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->logical_local_size = local_size;
+#endif
+}
+
+static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(local_size);
+
+ compiler->options = options;
+ compiler->scratches = scratches;
+ compiler->saveds = saveds;
+ compiler->fscratches = fscratches;
+ compiler->fsaveds = fsaveds;
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->logical_local_size = local_size;
+#endif
+}
+
+static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
+{
+ label->next = NULL;
+ label->size = compiler->size;
+ if (compiler->last_label)
+ compiler->last_label->next = label;
+ else
+ compiler->labels = label;
+ compiler->last_label = label;
+}
+
+static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_s32 flags)
+{
+ jump->next = NULL;
+ jump->flags = flags;
+ if (compiler->last_jump)
+ compiler->last_jump->next = jump;
+ else
+ compiler->jumps = jump;
+ compiler->last_jump = jump;
+}
+
+static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
+{
+ const_->next = NULL;
+ const_->addr = compiler->size;
+ if (compiler->last_const)
+ compiler->last_const->next = const_;
+ else
+ compiler->consts = const_;
+ compiler->last_const = const_;
+}
+
+#define ADDRESSING_DEPENDS_ON(exp, reg) \
+ (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+#define FUNCTION_CHECK_OP() \
+ CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
+ switch (GET_OPCODE(op)) { \
+ case SLJIT_NOT: \
+ case SLJIT_CLZ: \
+ case SLJIT_AND: \
+ case SLJIT_OR: \
+ case SLJIT_XOR: \
+ case SLJIT_SHL: \
+ case SLJIT_LSHR: \
+ case SLJIT_ASHR: \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_NEG: \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_MUL: \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_ADD: \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \
+ break; \
+ case SLJIT_SUB: \
+ break; \
+ case SLJIT_ADDC: \
+ case SLJIT_SUBC: \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \
+ break; \
+ case SLJIT_BREAKPOINT: \
+ case SLJIT_NOP: \
+ case SLJIT_LMUL_UW: \
+ case SLJIT_LMUL_SW: \
+ case SLJIT_MOV: \
+ case SLJIT_MOV_U32: \
+ case SLJIT_MOV_P: \
+ case SLJIT_MOVU: \
+ case SLJIT_MOVU_U32: \
+ case SLJIT_MOVU_P: \
+ /* Nothing allowed */ \
+ CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ break; \
+ default: \
+ /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ break; \
+ }
+
+#define FUNCTION_CHECK_FOP() \
+ CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
+ switch (GET_OPCODE(op)) { \
+ case SLJIT_CMP_F64: \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_SET_S))); \
+ break; \
+ default: \
+ /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ break; \
+ }
+
+#define FUNCTION_CHECK_IS_REG(r) \
+ (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
+ ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
+
+#define FUNCTION_CHECK_IS_REG_OR_UNUSED(r) \
+ ((r) == SLJIT_UNUSED || \
+ ((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
+ ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#define CHECK_NOT_VIRTUAL_REGISTER(p) \
+ CHECK_ARGUMENT((p) < SLJIT_R3 || (p) > SLJIT_R6);
+#else
+#define CHECK_NOT_VIRTUAL_REGISTER(p)
+#endif
+
+#define FUNCTION_CHECK_SRC(p, i) \
+ CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
+ if (FUNCTION_CHECK_IS_REG(p)) \
+ CHECK_ARGUMENT((i) == 0); \
+ else if ((p) == SLJIT_IMM) \
+ ; \
+ else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
+ CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
+ else { \
+ CHECK_ARGUMENT((p) & SLJIT_MEM); \
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
+ CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
+ if ((p) & OFFS_REG_MASK) { \
+ CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
+ CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
+ CHECK_ARGUMENT(!((i) & ~0x3)); \
+ } \
+ CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
+ }
+
+#define FUNCTION_CHECK_DST(p, i) \
+ CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
+ if (FUNCTION_CHECK_IS_REG_OR_UNUSED(p)) \
+ CHECK_ARGUMENT((i) == 0); \
+ else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
+ CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
+ else { \
+ CHECK_ARGUMENT((p) & SLJIT_MEM); \
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
+ CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
+ if ((p) & OFFS_REG_MASK) { \
+ CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
+ CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
+ CHECK_ARGUMENT(!((i) & ~0x3)); \
+ } \
+ CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
+ }
+
+#define FUNCTION_FCHECK(p, i) \
+ CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); \
+ if (((p) >= SLJIT_FR0 && (p) < (SLJIT_FR0 + compiler->fscratches)) || \
+ ((p) > (SLJIT_FS0 - compiler->fsaveds) && (p) <= SLJIT_FS0)) \
+ CHECK_ARGUMENT(i == 0); \
+ else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
+ CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
+ else { \
+ CHECK_ARGUMENT((p) & SLJIT_MEM); \
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
+ CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
+ if ((p) & OFFS_REG_MASK) { \
+ CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
+ CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
+ CHECK_ARGUMENT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SP) && !(i & ~0x3)); \
+ } \
+ CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
+ }
+
+#define FUNCTION_CHECK_OP1() \
+ if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \
+ CHECK_ARGUMENT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_SP); \
+ CHECK_ARGUMENT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_SP); \
+ if ((src & SLJIT_MEM) && (src & REG_MASK)) \
+ CHECK_ARGUMENT((dst & REG_MASK) != (src & REG_MASK) && OFFS_REG(dst) != (src & REG_MASK)); \
+ }
+
+#endif /* SLJIT_ARGUMENT_CHECKS */
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
+{
+ compiler->verbose = verbose;
+}
+
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#ifdef _WIN64
+# define SLJIT_PRINT_D "I64"
+#else
+# define SLJIT_PRINT_D "l"
+#endif
+#else
+# define SLJIT_PRINT_D ""
+#endif
+
+#define sljit_verbose_reg(compiler, r) \
+ do { \
+ if ((r) < (SLJIT_R0 + compiler->scratches)) \
+ fprintf(compiler->verbose, "r%d", (r) - SLJIT_R0); \
+ else \
+ fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - (r)); \
+ } while (0)
+
+#define sljit_verbose_param(compiler, p, i) \
+ if ((p) & SLJIT_IMM) \
+ fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \
+ else if ((p) & SLJIT_MEM) { \
+ if ((p) & REG_MASK) { \
+ fputc('[', compiler->verbose); \
+ sljit_verbose_reg(compiler, (p) & REG_MASK); \
+ if ((p) & OFFS_REG_MASK) { \
+ fprintf(compiler->verbose, " + "); \
+ sljit_verbose_reg(compiler, OFFS_REG(p)); \
+ if (i) \
+ fprintf(compiler->verbose, " * %d", 1 << (i)); \
+ } \
+ else if (i) \
+ fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); \
+ fputc(']', compiler->verbose); \
+ } \
+ else \
+ fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
+ } else if (p) \
+ sljit_verbose_reg(compiler, p); \
+ else \
+ fprintf(compiler->verbose, "unused");
+
+#define sljit_verbose_fparam(compiler, p, i) \
+ if ((p) & SLJIT_MEM) { \
+ if ((p) & REG_MASK) { \
+ fputc('[', compiler->verbose); \
+ sljit_verbose_reg(compiler, (p) & REG_MASK); \
+ if ((p) & OFFS_REG_MASK) { \
+ fprintf(compiler->verbose, " + "); \
+ sljit_verbose_reg(compiler, OFFS_REG(p)); \
+ if (i) \
+ fprintf(compiler->verbose, "%d", 1 << (i)); \
+ } \
+ else if (i) \
+ fprintf(compiler->verbose, "%" SLJIT_PRINT_D "d", (i)); \
+ fputc(']', compiler->verbose); \
+ } \
+ else \
+ fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
+ } \
+ else { \
+ if ((p) < (SLJIT_FR0 + compiler->fscratches)) \
+ fprintf(compiler->verbose, "fr%d", (p) - SLJIT_FR0); \
+ else \
+ fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \
+ }
+
+static const char* op0_names[] = {
+ (char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw",
+ (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s"
+};
+
+static const char* op1_names[] = {
+ (char*)"", (char*)".u8", (char*)".s8", (char*)".u16",
+ (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",
+ (char*)"", (char*)".u8", (char*)".s8", (char*)".u16",
+ (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",
+ (char*)"not", (char*)"neg", (char*)"clz",
+};
+
+static const char* op2_names[] = {
+ (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
+ (char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
+ (char*)"shl", (char*)"lshr", (char*)"ashr",
+};
+
+static const char* fop1_names[] = {
+ (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv",
+ (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg",
+ (char*)"abs",
+};
+
+static const char* fop2_names[] = {
+ (char*)"add", (char*)"sub", (char*)"mul", (char*)"div"
+};
+
+#define JUMP_POSTFIX(type) \
+ ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_I32_OP) ? "32" : "") \
+ : ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_F32_OP) ? ".f32" : ".f64") : ""))
+
+static char* jump_names[] = {
+ (char*)"equal", (char*)"not_equal",
+ (char*)"less", (char*)"greater_equal",
+ (char*)"greater", (char*)"less_equal",
+ (char*)"sig_less", (char*)"sig_greater_equal",
+ (char*)"sig_greater", (char*)"sig_less_equal",
+ (char*)"overflow", (char*)"not_overflow",
+ (char*)"mul_overflow", (char*)"mul_not_overflow",
+ (char*)"equal", (char*)"not_equal",
+ (char*)"less", (char*)"greater_equal",
+ (char*)"greater", (char*)"less_equal",
+ (char*)"unordered", (char*)"ordered",
+ (char*)"jump", (char*)"fast_call",
+ (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
+};
+
+#endif /* SLJIT_VERBOSE */
+
+/* --------------------------------------------------------------------- */
+/* Arch dependent */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+ || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ struct sljit_jump *jump;
+#endif
+
+ SLJIT_UNUSED_ARG(compiler);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(compiler->size > 0);
+ jump = compiler->jumps;
+ while (jump) {
+ /* All jumps have target. */
+ CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
+ jump = jump->next;
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT));
+ CHECK_ARGUMENT(args >= 0 && args <= 3);
+ CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(args <= saveds);
+ CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " enter options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
+ args, scratches, saveds, fscratches, fsaveds, local_size);
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT));
+ CHECK_ARGUMENT(args >= 0 && args <= 3);
+ CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(args <= saveds);
+ CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " set_context options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
+ args, scratches, saveds, fscratches, fsaveds, local_size);
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(compiler->scratches >= 0);
+ if (op != SLJIT_UNUSED) {
+ CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_P);
+ FUNCTION_CHECK_SRC(src, srcw);
+ }
+ else
+ CHECK_ARGUMENT(src == 0 && srcw == 0);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if (op == SLJIT_UNUSED)
+ fprintf(compiler->verbose, " return\n");
+ else {
+ fprintf(compiler->verbose, " return%s ", op1_names[op - SLJIT_OP1_BASE]);
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fast_enter ");
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fast_return ");
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
+ || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW));
+ CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ {
+ fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
+ if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) {
+ fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w");
+ }
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
+ FUNCTION_CHECK_OP();
+ FUNCTION_CHECK_SRC(src, srcw);
+ FUNCTION_CHECK_DST(dst, dstw);
+ FUNCTION_CHECK_OP1();
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if (GET_OPCODE(op) <= SLJIT_MOVU_P)
+ {
+ fprintf(compiler->verbose, " mov%s%s%s ", (GET_OPCODE(op) >= SLJIT_MOVU) ? "u" : "",
+ !(op & SLJIT_I32_OP) ? "" : "32", (op != SLJIT_MOV32 && op != SLJIT_MOVU32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : "");
+ }
+ else
+ {
+ fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
+ !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s",
+ !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
+ }
+
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
+ FUNCTION_CHECK_OP();
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
+ !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s",
+ !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg)
+{
+ SLJIT_UNUSED_ARG(reg);
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS);
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg)
+{
+ SLJIT_UNUSED_ARG(reg);
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ int i;
+#endif
+
+ SLJIT_UNUSED_ARG(compiler);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(instruction);
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+ CHECK_ARGUMENT(size > 0 && size < 16);
+#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
+ || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
+#else
+ CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
+#endif
+
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " op_custom");
+ for (i = 0; i < size; i++)
+ fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(sljit_is_fpu_available());
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);
+ FUNCTION_CHECK_FOP();
+ FUNCTION_FCHECK(src, srcw);
+ FUNCTION_FCHECK(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
+ fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],
+ (op & SLJIT_F32_OP) ? ".f32.from.f64" : ".f64.from.f32");
+ else
+ fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
+ (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+
+ sljit_verbose_fparam(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(sljit_is_fpu_available());
+ CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
+ FUNCTION_CHECK_FOP();
+ FUNCTION_FCHECK(src1, src1w);
+ FUNCTION_FCHECK(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s%s ", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64",
+ (op & SLJIT_SET_E) ? ".e" : "", (op & SLJIT_SET_S) ? ".s" : "");
+ sljit_verbose_fparam(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(compiler, src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(sljit_is_fpu_available());
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64);
+ FUNCTION_CHECK_FOP();
+ FUNCTION_FCHECK(src, srcw);
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
+ (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw",
+ (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(sljit_is_fpu_available());
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32);
+ FUNCTION_CHECK_FOP();
+ FUNCTION_CHECK_SRC(src, srcw);
+ FUNCTION_FCHECK(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
+ (op & SLJIT_F32_OP) ? ".f32" : ".f64",
+ (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw");
+ sljit_verbose_fparam(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(sljit_is_fpu_available());
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);
+ FUNCTION_CHECK_FOP();
+ FUNCTION_FCHECK(src1, src1w);
+ FUNCTION_FCHECK(src2, src2w);
+ FUNCTION_FCHECK(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+ sljit_verbose_fparam(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(compiler, src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, "label:\n");
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3);
+ CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP));
+ CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
+ jump_names[type & 0xff], JUMP_POSTFIX(type));
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
+ jump_names[type & 0xff], (type & SLJIT_I32_OP) ? "32" : "");
+ sljit_verbose_param(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(sljit_is_fpu_available());
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_F32_OP)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64);
+ FUNCTION_FCHECK(src1, src1w);
+ FUNCTION_FCHECK(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
+ jump_names[type & 0xff], (type & SLJIT_F32_OP) ? ".f32" : ".f64");
+ sljit_verbose_fparam(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(compiler, src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+ CHECK_ARGUMENT(type <= SLJIT_CALL0 || (type - SLJIT_CALL0) <= compiler->scratches);
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " ijump.%s ", jump_names[type]);
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
+ CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_U32 || GET_OPCODE(op) == SLJIT_MOV_S32
+ || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
+ CHECK_ARGUMENT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0);
+ CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS));
+ if (GET_OPCODE(op) < SLJIT_ADD) {
+ CHECK_ARGUMENT(src == SLJIT_UNUSED && srcw == 0);
+ } else {
+ CHECK_ARGUMENT(src == dst && srcw == dstw);
+ }
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " flags %s%s%s%s, ",
+ !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k",
+ GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
+ GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_I32_OP) ? "32" : ""));
+ sljit_verbose_param(compiler, dst, dstw);
+ if (src != SLJIT_UNUSED) {
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src, srcw);
+ }
+ fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type));
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
+{
+ SLJIT_UNUSED_ARG(offset);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " local_base ");
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ SLJIT_UNUSED_ARG(init_value);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " const ");
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
+
+#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
+ SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \
+ invalid_float_opcodes); \
+ if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \
+ if (GET_OPCODE(op) == SLJIT_CMP_F64) { \
+ CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \
+ ADJUST_LOCAL_OFFSET(dst, dstw); \
+ ADJUST_LOCAL_OFFSET(src, srcw); \
+ return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
+ } \
+ if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \
+ CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \
+ ADJUST_LOCAL_OFFSET(dst, dstw); \
+ ADJUST_LOCAL_OFFSET(src, srcw); \
+ return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \
+ } \
+ CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \
+ ADJUST_LOCAL_OFFSET(dst, dstw); \
+ ADJUST_LOCAL_OFFSET(src, srcw); \
+ return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \
+ } \
+ CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \
+ ADJUST_LOCAL_OFFSET(dst, dstw); \
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ /* Return if don't need to do anything. */
+ if (op == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+ /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
+ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
+ return SLJIT_SUCCESS;
+#else
+ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
+ return SLJIT_SUCCESS;
+#endif
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+ || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
+}
+
+/* CPU description section */
+
+#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
+#define SLJIT_CPUINFO_PART1 " 32bit ("
+#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#define SLJIT_CPUINFO_PART1 " 64bit ("
+#else
+#error "Internal error: CPU type info missing"
+#endif
+
+#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#define SLJIT_CPUINFO_PART2 "little endian + "
+#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
+#define SLJIT_CPUINFO_PART2 "big endian + "
+#else
+#error "Internal error: CPU type info missing"
+#endif
+
+#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
+#define SLJIT_CPUINFO_PART3 "unaligned)"
+#else
+#define SLJIT_CPUINFO_PART3 "aligned)"
+#endif
+
+#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+# include "sljitNativeX86_common.c"
+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+# include "sljitNativeARM_32.c"
+#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+# include "sljitNativeARM_32.c"
+#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+# include "sljitNativeARM_T2_32.c"
+#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
+# include "sljitNativeARM_64.c"
+#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+# include "sljitNativePPC_common.c"
+#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+# include "sljitNativeMIPS_common.c"
+#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
+# include "sljitNativeSPARC_common.c"
+#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+# include "sljitNativeTILEGX_64.c"
+#endif
+
+#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ /* Default compare for most architectures. */
+ sljit_s32 flags, tmp_src, condition;
+ sljit_sw tmp_srcw;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
+
+ condition = type & 0xff;
+#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
+ if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {
+ if ((src1 & SLJIT_IMM) && !src1w) {
+ src1 = src2;
+ src1w = src2w;
+ src2 = SLJIT_IMM;
+ src2w = 0;
+ }
+ if ((src2 & SLJIT_IMM) && !src2w)
+ return emit_cmp_to0(compiler, type, src1, src1w);
+ }
+#endif
+
+ if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
+ /* Immediate is prefered as second argument by most architectures. */
+ switch (condition) {
+ case SLJIT_LESS:
+ condition = SLJIT_GREATER;
+ break;
+ case SLJIT_GREATER_EQUAL:
+ condition = SLJIT_LESS_EQUAL;
+ break;
+ case SLJIT_GREATER:
+ condition = SLJIT_LESS;
+ break;
+ case SLJIT_LESS_EQUAL:
+ condition = SLJIT_GREATER_EQUAL;
+ break;
+ case SLJIT_SIG_LESS:
+ condition = SLJIT_SIG_GREATER;
+ break;
+ case SLJIT_SIG_GREATER_EQUAL:
+ condition = SLJIT_SIG_LESS_EQUAL;
+ break;
+ case SLJIT_SIG_GREATER:
+ condition = SLJIT_SIG_LESS;
+ break;
+ case SLJIT_SIG_LESS_EQUAL:
+ condition = SLJIT_SIG_GREATER_EQUAL;
+ break;
+ }
+ type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP));
+ tmp_src = src1;
+ src1 = src2;
+ src2 = tmp_src;
+ tmp_srcw = src1w;
+ src1w = src2w;
+ src2w = tmp_srcw;
+ }
+
+ if (condition <= SLJIT_NOT_ZERO)
+ flags = SLJIT_SET_E;
+ else if (condition <= SLJIT_LESS_EQUAL)
+ flags = SLJIT_SET_U;
+ else
+ flags = SLJIT_SET_S;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_I32_OP),
+ SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 flags, condition;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
+
+ condition = type & 0xff;
+ flags = (condition <= SLJIT_NOT_EQUAL_F64) ? SLJIT_SET_E : SLJIT_SET_S;
+ if (type & SLJIT_F32_OP)
+ flags |= SLJIT_F32_OP;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ sljit_emit_fop1(compiler, SLJIT_CMP_F64 | flags, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+}
+
+#endif
+
+#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
+
+ ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ if (offset != 0)
+ return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
+ return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
+}
+
+#endif
+
+#else /* SLJIT_CONFIG_UNSUPPORTED */
+
+/* Empty function bodies for those machines, which are not (yet) supported. */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "unsupported";
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
+{
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(verbose);
+ SLJIT_ASSERT_STOP();
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ SLJIT_UNUSED_ARG(code);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(options);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(scratches);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(fscratches);
+ SLJIT_UNUSED_ARG(fsaveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(options);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(scratches);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(fscratches);
+ SLJIT_UNUSED_ARG(fsaveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ SLJIT_ASSERT_STOP();
+ return reg;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(instruction);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+ SLJIT_ASSERT_STOP();
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
+{
+ SLJIT_UNUSED_ARG(jump);
+ SLJIT_UNUSED_ARG(label);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
+{
+ SLJIT_UNUSED_ARG(jump);
+ SLJIT_UNUSED_ARG(target);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(offset);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(initval);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ SLJIT_UNUSED_ARG(addr);
+ SLJIT_UNUSED_ARG(new_target);
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ SLJIT_UNUSED_ARG(addr);
+ SLJIT_UNUSED_ARG(new_constant);
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_ASSERT_STOP();
+}
+
+#endif
diff --git a/thirdparty/pcre2/src/sljit/sljitLir.h b/thirdparty/pcre2/src/sljit/sljitLir.h
new file mode 100644
index 0000000000..f24f556b56
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitLir.h
@@ -0,0 +1,1269 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_LIR_H_
+#define _SLJIT_LIR_H_
+
+/*
+ ------------------------------------------------------------------------
+ Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)
+ ------------------------------------------------------------------------
+
+ Short description
+ Advantages:
+ - The execution can be continued from any LIR instruction. In other
+ words, it is possible to jump to any label from anywhere, even from
+ a code fragment, which is compiled later, if both compiled code
+ shares the same context. See sljit_emit_enter for more details
+ - Supports self modifying code: target of (conditional) jump and call
+ instructions and some constant values can be dynamically modified
+ during runtime
+ - although it is not suggested to do it frequently
+ - can be used for inline caching: save an important value once
+ in the instruction stream
+ - since this feature limits the optimization possibilities, a
+ special flag must be passed at compile time when these
+ instructions are emitted
+ - A fixed stack space can be allocated for local variables
+ - The compiler is thread-safe
+ - The compiler is highly configurable through preprocessor macros.
+ You can disable unneeded features (multithreading in single
+ threaded applications), and you can use your own system functions
+ (including memory allocators). See sljitConfig.h
+ Disadvantages:
+ - No automatic register allocation, and temporary results are
+ not stored on the stack. (hence the name comes)
+ In practice:
+ - This approach is very effective for interpreters
+ - One of the saved registers typically points to a stack interface
+ - It can jump to any exception handler anytime (even if it belongs
+ to another function)
+ - Hot paths can be modified during runtime reflecting the changes
+ of the fastest execution path of the dynamic language
+ - SLJIT supports complex memory addressing modes
+ - mainly position and context independent code (except some cases)
+
+ For valgrind users:
+ - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
+*/
+
+#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
+#include "sljitConfig.h"
+#endif
+
+/* The following header file defines useful macros for fine tuning
+sljit based code generators. They are listed in the beginning
+of sljitConfigInternal.h */
+
+#include "sljitConfigInternal.h"
+
+/* --------------------------------------------------------------------- */
+/* Error codes */
+/* --------------------------------------------------------------------- */
+
+/* Indicates no error. */
+#define SLJIT_SUCCESS 0
+/* After the call of sljit_generate_code(), the error code of the compiler
+ is set to this value to avoid future sljit calls (in debug mode at least).
+ The complier should be freed after sljit_generate_code(). */
+#define SLJIT_ERR_COMPILED 1
+/* Cannot allocate non executable memory. */
+#define SLJIT_ERR_ALLOC_FAILED 2
+/* Cannot allocate executable memory.
+ Only for sljit_generate_code() */
+#define SLJIT_ERR_EX_ALLOC_FAILED 3
+/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */
+#define SLJIT_ERR_UNSUPPORTED 4
+/* An ivalid argument is passed to any SLJIT function. */
+#define SLJIT_ERR_BAD_ARGUMENT 5
+/* Dynamic code modification is not enabled. */
+#define SLJIT_ERR_DYN_CODE_MOD 6
+
+/* --------------------------------------------------------------------- */
+/* Registers */
+/* --------------------------------------------------------------------- */
+
+/*
+ Scratch (R) registers: registers whose may not preserve their values
+ across function calls.
+
+ Saved (S) registers: registers whose preserve their values across
+ function calls.
+
+ The scratch and saved register sets are overlap. The last scratch register
+ is the first saved register, the one before the last is the second saved
+ register, and so on.
+
+ If an architecture provides two scratch and three saved registers,
+ its scratch and saved register sets are the following:
+
+ R0 | [S4] | R0 and S4 represent the same physical register
+ R1 | [S3] | R1 and S3 represent the same physical register
+ [R2] | S2 | R2 and S2 represent the same physical register
+ [R3] | S1 | R3 and S1 represent the same physical register
+ [R4] | S0 | R4 and S0 represent the same physical register
+
+ Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and
+ SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture.
+
+ Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 10
+ and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 5. However, 4 registers
+ are virtual on x86-32. See below.
+
+ The purpose of this definition is convenience. Although a register
+ is either scratch register or saved register, SLJIT allows accessing
+ them from the other set. For example, four registers can be used as
+ scratch registers and the fifth one as saved register on the architecture
+ above. Of course the last two scratch registers (R2 and R3) from this
+ four will be saved on the stack, because they are defined as saved
+ registers in the application binary interface. Still R2 and R3 can be
+ used for referencing to these registers instead of S2 and S1, which
+ makes easier to write platform independent code. Scratch registers
+ can be saved registers in a similar way, but these extra saved
+ registers will not be preserved across function calls! Hence the
+ application must save them on those platforms, where the number of
+ saved registers is too low. This can be done by copy them onto
+ the stack and restore them after a function call.
+
+ Note: To emphasize that registers assigned to R2-R4 are saved
+ registers, they are enclosed by square brackets. S3-S4
+ are marked in a similar way.
+
+ Note: sljit_emit_enter and sljit_set_context defines whether a register
+ is S or R register. E.g: when 3 scratches and 1 saved is mapped
+ by sljit_emit_enter, the allowed register set will be: R0-R2 and
+ S0. Although S2 is mapped to the same position as R2, it does not
+ available in the current configuration. Furthermore the R3 (S1)
+ register does not available as well.
+*/
+
+/* When SLJIT_UNUSED is specified as destination, the result is discarded. */
+#define SLJIT_UNUSED 0
+
+/* Scratch registers. */
+#define SLJIT_R0 1
+#define SLJIT_R1 2
+#define SLJIT_R2 3
+/* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they
+ are allocated on the stack). These registers are called virtual
+ and cannot be used for memory addressing (cannot be part of
+ any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
+ limitation on other CPUs. See sljit_get_register_index(). */
+#define SLJIT_R3 4
+#define SLJIT_R4 5
+#define SLJIT_R5 6
+#define SLJIT_R6 7
+#define SLJIT_R7 8
+#define SLJIT_R8 9
+#define SLJIT_R9 10
+/* All R registers provided by the architecture can be accessed by SLJIT_R(i)
+ The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */
+#define SLJIT_R(i) (1 + (i))
+
+/* Saved registers. */
+#define SLJIT_S0 (SLJIT_NUMBER_OF_REGISTERS)
+#define SLJIT_S1 (SLJIT_NUMBER_OF_REGISTERS - 1)
+#define SLJIT_S2 (SLJIT_NUMBER_OF_REGISTERS - 2)
+/* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they
+ are allocated on the stack). These registers are called virtual
+ and cannot be used for memory addressing (cannot be part of
+ any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
+ limitation on other CPUs. See sljit_get_register_index(). */
+#define SLJIT_S3 (SLJIT_NUMBER_OF_REGISTERS - 3)
+#define SLJIT_S4 (SLJIT_NUMBER_OF_REGISTERS - 4)
+#define SLJIT_S5 (SLJIT_NUMBER_OF_REGISTERS - 5)
+#define SLJIT_S6 (SLJIT_NUMBER_OF_REGISTERS - 6)
+#define SLJIT_S7 (SLJIT_NUMBER_OF_REGISTERS - 7)
+#define SLJIT_S8 (SLJIT_NUMBER_OF_REGISTERS - 8)
+#define SLJIT_S9 (SLJIT_NUMBER_OF_REGISTERS - 9)
+/* All S registers provided by the architecture can be accessed by SLJIT_S(i)
+ The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */
+#define SLJIT_S(i) (SLJIT_NUMBER_OF_REGISTERS - (i))
+
+/* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */
+#define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1)
+
+/* The SLJIT_SP provides direct access to the linear stack space allocated by
+ sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP).
+ The immediate offset is extended by the relative stack offset automatically.
+ The sljit_get_local_base can be used to obtain the absolute offset. */
+#define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1)
+
+/* Return with machine word. */
+
+#define SLJIT_RETURN_REG SLJIT_R0
+
+/* x86 prefers specific registers for special purposes. In case of shift
+ by register it supports only SLJIT_R2 for shift argument
+ (which is the src2 argument of sljit_emit_op2). If another register is
+ used, sljit must exchange data between registers which cause a minor
+ slowdown. Other architectures has no such limitation. */
+
+#define SLJIT_PREF_SHIFT_REG SLJIT_R2
+
+/* --------------------------------------------------------------------- */
+/* Floating point registers */
+/* --------------------------------------------------------------------- */
+
+/* Each floating point register can store a 32 or a 64 bit precision
+ value. The FR and FS register sets are overlap in the same way as R
+ and S register sets. See above. */
+
+/* Note: SLJIT_UNUSED as destination is not valid for floating point
+ operations, since they cannot be used for setting flags. */
+
+/* Floating point scratch registers. */
+#define SLJIT_FR0 1
+#define SLJIT_FR1 2
+#define SLJIT_FR2 3
+#define SLJIT_FR3 4
+#define SLJIT_FR4 5
+#define SLJIT_FR5 6
+/* All FR registers provided by the architecture can be accessed by SLJIT_FR(i)
+ The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */
+#define SLJIT_FR(i) (1 + (i))
+
+/* Floating point saved registers. */
+#define SLJIT_FS0 (SLJIT_NUMBER_OF_FLOAT_REGISTERS)
+#define SLJIT_FS1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1)
+#define SLJIT_FS2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2)
+#define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3)
+#define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4)
+#define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5)
+/* All S registers provided by the architecture can be accessed by SLJIT_FS(i)
+ The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */
+#define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i))
+
+/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */
+#define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1)
+
+/* --------------------------------------------------------------------- */
+/* Main structures and functions */
+/* --------------------------------------------------------------------- */
+
+/*
+ The following structures are private, and can be changed in the
+ future. Keeping them here allows code inlining.
+*/
+
+struct sljit_memory_fragment {
+ struct sljit_memory_fragment *next;
+ sljit_uw used_size;
+ /* Must be aligned to sljit_sw. */
+ sljit_u8 memory[1];
+};
+
+struct sljit_label {
+ struct sljit_label *next;
+ sljit_uw addr;
+ /* The maximum size difference. */
+ sljit_uw size;
+};
+
+struct sljit_jump {
+ struct sljit_jump *next;
+ sljit_uw addr;
+ sljit_sw flags;
+ union {
+ sljit_uw target;
+ struct sljit_label* label;
+ } u;
+};
+
+struct sljit_const {
+ struct sljit_const *next;
+ sljit_uw addr;
+};
+
+struct sljit_compiler {
+ sljit_s32 error;
+ sljit_s32 options;
+
+ struct sljit_label *labels;
+ struct sljit_jump *jumps;
+ struct sljit_const *consts;
+ struct sljit_label *last_label;
+ struct sljit_jump *last_jump;
+ struct sljit_const *last_const;
+
+ void *allocator_data;
+ struct sljit_memory_fragment *buf;
+ struct sljit_memory_fragment *abuf;
+
+ /* Used scratch registers. */
+ sljit_s32 scratches;
+ /* Used saved registers. */
+ sljit_s32 saveds;
+ /* Used float scratch registers. */
+ sljit_s32 fscratches;
+ /* Used float saved registers. */
+ sljit_s32 fsaveds;
+ /* Local stack size. */
+ sljit_s32 local_size;
+ /* Code size. */
+ sljit_uw size;
+ /* Relative offset of the executable mapping from the writable mapping. */
+ sljit_uw executable_offset;
+ /* Executable size for statistical purposes. */
+ sljit_uw executable_size;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_s32 args;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ sljit_s32 mode32;
+#endif
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+ sljit_s32 flags_saved;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ /* Constant pool handling. */
+ sljit_uw *cpool;
+ sljit_u8 *cpool_unique;
+ sljit_uw cpool_diff;
+ sljit_uw cpool_fill;
+ /* Other members. */
+ /* Contains pointer, "ldr pc, [...]" pairs. */
+ sljit_uw patches;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ /* Temporary fields. */
+ sljit_uw shift_imm;
+ sljit_s32 cache_arg;
+ sljit_sw cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ sljit_s32 cache_arg;
+ sljit_sw cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
+ sljit_s32 cache_arg;
+ sljit_sw cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+ sljit_sw imm;
+ sljit_s32 cache_arg;
+ sljit_sw cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+ sljit_s32 delay_slot;
+ sljit_s32 cache_arg;
+ sljit_sw cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ sljit_s32 delay_slot;
+ sljit_s32 cache_arg;
+ sljit_sw cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+ sljit_s32 cache_arg;
+ sljit_sw cache_argw;
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ FILE* verbose;
+#endif
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+ || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ /* Local size passed to the functions. */
+ sljit_s32 logical_local_size;
+#endif
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+ || (defined SLJIT_DEBUG && SLJIT_DEBUG) \
+ || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ sljit_s32 skip_checks;
+#endif
+};
+
+/* --------------------------------------------------------------------- */
+/* Main functions */
+/* --------------------------------------------------------------------- */
+
+/* Creates an sljit compiler. The allocator_data is required by some
+ custom memory managers. This pointer is passed to SLJIT_MALLOC
+ and SLJIT_FREE macros. Most allocators (including the default
+ one) ignores this value, and it is recommended to pass NULL
+ as a dummy value for allocator_data.
+
+ Returns NULL if failed. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);
+
+/* Frees everything except the compiled machine code. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
+
+/* Returns the current error code. If an error is occurred, future sljit
+ calls which uses the same compiler argument returns early with the same
+ error code. Thus there is no need for checking the error after every
+ call, it is enough to do it before the code is compiled. Removing
+ these checks increases the performance of the compiling process. */
+static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
+
+/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except
+ if an error was detected before. After the error code is set
+ the compiler behaves as if the allocation failure happened
+ during an sljit function call. This can greatly simplify error
+ checking, since only the compiler status needs to be checked
+ after the compilation. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler);
+
+/*
+ Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
+ and <= 128 bytes on 64 bit architectures. The memory area is owned by the
+ compiler, and freed by sljit_free_compiler. The returned pointer is
+ sizeof(sljit_sw) aligned. Excellent for allocating small blocks during
+ the compiling, and no need to worry about freeing them. The size is
+ enough to contain at most 16 pointers. If the size is outside of the range,
+ the function will return with NULL. However, this return value does not
+ indicate that there is no more memory (does not set the current error code
+ of the compiler to out-of-memory status).
+*/
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+/* Passing NULL disables verbose. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
+#endif
+
+/*
+ Create executable code from the sljit instruction stream. This is the final step
+ of the code generation so no more instructions can be added after this call.
+*/
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
+
+/* Free executable code. */
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
+
+/*
+ When the protected executable allocator is used the JIT code is mapped
+ twice. The first mapping has read/write and the second mapping has read/exec
+ permissions. This function returns with the relative offset of the executable
+ mapping using the writable mapping as the base after the machine code is
+ successfully generated. The returned value is always 0 for the normal executable
+ allocator, since it uses only one mapping with read/write/exec permissions.
+ Dynamic code modifications requires this value.
+
+ Before a successful code generation, this function returns with 0.
+*/
+static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; }
+
+/*
+ The executable memory consumption of the generated code can be retrieved by
+ this function. The returned value can be used for statistical purposes.
+
+ Before a successful code generation, this function returns with 0.
+*/
+static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
+
+/* Instruction generation. Returns with any error code. If there is no
+ error, they return with SLJIT_SUCCESS. */
+
+/*
+ The executable code is a function call from the viewpoint of the C
+ language. The function calls must obey to the ABI (Application
+ Binary Interface) of the platform, which specify the purpose of
+ all machine registers and stack handling among other things. The
+ sljit_emit_enter function emits the necessary instructions for
+ setting up a new context for the executable code and moves function
+ arguments to the saved registers. Furthermore the options argument
+ can be used to pass configuration options to the compiler. The
+ available options are listed before sljit_emit_enter.
+
+ The number of sljit_sw arguments passed to the generated function
+ are specified in the "args" parameter. The number of arguments must
+ be less than or equal to 3. The first argument goes to SLJIT_S0,
+ the second goes to SLJIT_S1 and so on. The register set used by
+ the function must be declared as well. The number of scratch and
+ saved registers used by the function must be passed to sljit_emit_enter.
+ Only R registers between R0 and "scratches" argument can be used
+ later. E.g. if "scratches" is set to 2, the register set will be
+ limited to R0 and R1. The S registers and the floating point
+ registers ("fscratches" and "fsaveds") are specified in a similar
+ way. The sljit_emit_enter is also capable of allocating a stack
+ space for local variables. The "local_size" argument contains the
+ size in bytes of this local area and its staring address is stored
+ in SLJIT_SP. The memory area between SLJIT_SP (inclusive) and
+ SLJIT_SP + local_size (exclusive) can be modified freely until
+ the function returns. The stack space is not initialized.
+
+ Note: the following conditions must met:
+ 0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS
+ 0 <= saveds <= SLJIT_NUMBER_OF_REGISTERS
+ scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS
+ 0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
+ 0 <= fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
+ fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
+
+ Note: every call of sljit_emit_enter and sljit_set_context
+ overwrites the previous context.
+*/
+
+/* The absolute address returned by sljit_get_local_base with
+offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */
+#define SLJIT_DOUBLE_ALIGNMENT 0x00000001
+
+/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */
+#define SLJIT_MAX_LOCAL_SIZE 65536
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
+
+/* The machine code has a context (which contains the local stack space size,
+ number of used registers, etc.) which initialized by sljit_emit_enter. Several
+ functions (like sljit_emit_return) requres this context to be able to generate
+ the appropriate code. However, some code fragments (like inline cache) may have
+ no normal entry point so their context is unknown for the compiler. Their context
+ can be provided to the compiler by the sljit_set_context function.
+
+ Note: every call of sljit_emit_enter and sljit_set_context overwrites
+ the previous context. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
+
+/* Return from machine code. The op argument can be SLJIT_UNUSED which means the
+ function does not return with anything or any opcode between SLJIT_MOV and
+ SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op
+ is SLJIT_UNUSED, otherwise see below the description about source and
+ destination arguments. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw);
+
+/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and
+ even the stack frame is passed to the callee. The return address is preserved in
+ dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function
+ is sljit_p), and sljit_emit_fast_return can use this as a return value later. */
+
+/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine
+ instructions are needed. Excellent for small uility functions, where saving registers
+ and setting up a new stack frame would cost too much performance. However, it is still
+ possible to return to the address of the caller (or anywhere else). */
+
+/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */
+
+/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
+ since many architectures do clever branch prediction on call / return instruction pairs. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw);
+
+/*
+ Source and destination values for arithmetical instructions
+ imm - a simple immediate value (cannot be used as a destination)
+ reg - any of the registers (immediate argument must be 0)
+ [imm] - absolute immediate memory address
+ [reg+imm] - indirect memory address
+ [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)
+ useful for (byte, half, int, sljit_sw) array access
+ (fully supported by both x86 and ARM architectures, and cheap operation on others)
+*/
+
+/*
+ IMPORATNT NOTE: memory access MUST be naturally aligned except
+ SLJIT_UNALIGNED macro is defined and its value is 1.
+
+ length | alignment
+ ---------+-----------
+ byte | 1 byte (any physical_address is accepted)
+ half | 2 byte (physical_address & 0x1 == 0)
+ int | 4 byte (physical_address & 0x3 == 0)
+ word | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
+ | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
+ pointer | size of sljit_p type (4 byte on 32 bit machines, 4 or 8 byte
+ | on 64 bit machines)
+
+ Note: Different architectures have different addressing limitations.
+ A single instruction is enough for the following addressing
+ modes. Other adrressing modes are emulated by instruction
+ sequences. This information could help to improve those code
+ generators which focuses only a few architectures.
+
+ x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)
+ [reg+(reg<<imm)] is supported
+ [imm], -2^32+1 <= imm <= 2^32-1 is supported
+ Write-back is not supported
+ arm: [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed
+ bytes, any halfs or floating point values)
+ [reg+(reg<<imm)] is supported
+ Write-back is supported
+ arm-t2: [reg+imm], -255 <= imm <= 4095
+ [reg+(reg<<imm)] is supported
+ Write back is supported only for [reg+imm], where -255 <= imm <= 255
+ ppc: [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
+ signed load on 64 bit requires immediates divisible by 4.
+ [reg+imm] is not supported for signed 8 bit values.
+ [reg+reg] is supported
+ Write-back is supported except for one instruction: 32 bit signed
+ load with [reg+imm] addressing mode on 64 bit.
+ mips: [reg+imm], -65536 <= imm <= 65535
+ sparc: [reg+imm], -4096 <= imm <= 4095
+ [reg+reg] is supported
+*/
+
+/* Register output: simply the name of the register.
+ For destination, you can use SLJIT_UNUSED as well. */
+#define SLJIT_MEM 0x80
+#define SLJIT_MEM0() (SLJIT_MEM)
+#define SLJIT_MEM1(r1) (SLJIT_MEM | (r1))
+#define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8))
+#define SLJIT_IMM 0x40
+
+/* Set 32 bit operation mode (I) on 64 bit CPUs. This flag is ignored on 32
+ bit CPUs. When this flag is set for an arithmetic operation, only the
+ lower 32 bit of the input register(s) are used, and the CPU status flags
+ are set according to the 32 bit result. Although the higher 32 bit of
+ the input and the result registers are not defined by SLJIT, it might be
+ defined by the CPU architecture (e.g. MIPS). To satisfy these requirements
+ all source registers must be computed by operations where this flag is
+ also set. In other words 32 and 64 bit arithmetic operations cannot be
+ mixed. The only exception is SLJIT_IMOV and SLJIT_IMOVU whose source
+ register can hold any 32 or 64 bit value. This source register is
+ converted to a 32 bit compatible format. SLJIT does not generate any
+ instructions on certain CPUs (e.g. on x86 and ARM) if the source and
+ destination operands are the same registers. Affects sljit_emit_op0,
+ sljit_emit_op1 and sljit_emit_op2. */
+#define SLJIT_I32_OP 0x100
+
+/* F32 precision mode (SP). This flag is similar to SLJIT_I32_OP, just
+ it applies to floating point registers (it is even the same bit). When
+ this flag is passed, the CPU performs 32 bit floating point operations.
+ Similar to SLJIT_I32_OP, all register arguments must be computed by
+ floating point operations where this flag is also set. Affects
+ sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */
+#define SLJIT_F32_OP 0x100
+
+/* Common CPU status flags for all architectures (x86, ARM, PPC)
+ - carry flag
+ - overflow flag
+ - zero flag
+ - negative/positive flag (depends on arc)
+ On mips, these flags are emulated by software. */
+
+/* By default, the instructions may, or may not set the CPU status flags.
+ Forcing to set or keep status flags can be done with the following flags: */
+
+/* Note: sljit tries to emit the minimum number of instructions. Using these
+ flags can increase them, so use them wisely to avoid unnecessary code generation. */
+
+/* Set Equal (Zero) status flag (E). */
+#define SLJIT_SET_E 0x0200
+/* Set unsigned status flag (U). */
+#define SLJIT_SET_U 0x0400
+/* Set signed status flag (S). */
+#define SLJIT_SET_S 0x0800
+/* Set signed overflow flag (O). */
+#define SLJIT_SET_O 0x1000
+/* Set carry flag (C).
+ Note: Kinda unsigned overflow, but behaves differently on various cpus. */
+#define SLJIT_SET_C 0x2000
+/* Do not modify the flags (K).
+ Note: This flag cannot be combined with any other SLJIT_SET_* flag. */
+#define SLJIT_KEEP_FLAGS 0x4000
+
+/* Notes:
+ - you cannot postpone conditional jump instructions except if noted that
+ the instruction does not set flags (See: SLJIT_KEEP_FLAGS).
+ - flag combinations: '|' means 'logical or'. */
+
+/* Starting index of opcodes for sljit_emit_op0. */
+#define SLJIT_OP0_BASE 0
+
+/* Flags: - (never set any flags)
+ Note: breakpoint instruction is not supported by all architectures (e.g. ppc)
+ It falls back to SLJIT_NOP in those cases. */
+#define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0)
+/* Flags: - (never set any flags)
+ Note: may or may not cause an extra cycle wait
+ it can even decrease the runtime in a few cases. */
+#define SLJIT_NOP (SLJIT_OP0_BASE + 1)
+/* Flags: - (may destroy flags)
+ Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
+ Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
+#define SLJIT_LMUL_UW (SLJIT_OP0_BASE + 2)
+/* Flags: - (may destroy flags)
+ Signed multiplication of SLJIT_R0 and SLJIT_R1.
+ Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
+#define SLJIT_LMUL_SW (SLJIT_OP0_BASE + 3)
+/* Flags: I - (may destroy flags)
+ Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
+ The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
+ Note: if SLJIT_R1 is 0, the behaviour is undefined. */
+#define SLJIT_DIVMOD_UW (SLJIT_OP0_BASE + 4)
+#define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_I32_OP)
+/* Flags: I - (may destroy flags)
+ Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
+ The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
+ Note: if SLJIT_R1 is 0, the behaviour is undefined.
+ Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
+ the behaviour is undefined. */
+#define SLJIT_DIVMOD_SW (SLJIT_OP0_BASE + 5)
+#define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_I32_OP)
+/* Flags: I - (may destroy flags)
+ Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
+ The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
+ Note: if SLJIT_R1 is 0, the behaviour is undefined. */
+#define SLJIT_DIV_UW (SLJIT_OP0_BASE + 6)
+#define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_I32_OP)
+/* Flags: I - (may destroy flags)
+ Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
+ The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
+ Note: if SLJIT_R1 is 0, the behaviour is undefined.
+ Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
+ the behaviour is undefined. */
+#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7)
+#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);
+
+/* Starting index of opcodes for sljit_emit_op1. */
+#define SLJIT_OP1_BASE 32
+
+/* Notes for MOV instructions:
+ U = Mov with update (pre form). If source or destination defined as SLJIT_MEM1(r1)
+ or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
+ UB = unsigned byte (8 bit)
+ SB = signed byte (8 bit)
+ UH = unsigned half (16 bit)
+ SH = signed half (16 bit)
+ UI = unsigned int (32 bit)
+ SI = signed int (32 bit)
+ P = pointer (sljit_p) size */
+
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV (SLJIT_OP1_BASE + 0)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOV_U8 (SLJIT_OP1_BASE + 1)
+#define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOV_S8 (SLJIT_OP1_BASE + 2)
+#define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOV_U16 (SLJIT_OP1_BASE + 3)
+#define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOV_S16 (SLJIT_OP1_BASE + 4)
+#define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags)
+ Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */
+#define SLJIT_MOV_U32 (SLJIT_OP1_BASE + 5)
+/* Flags: I - (never set any flags)
+ Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */
+#define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOV32 (SLJIT_MOV_S32 | SLJIT_I32_OP)
+/* Flags: - (never set any flags) */
+#define SLJIT_MOV_P (SLJIT_OP1_BASE + 7)
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU (SLJIT_OP1_BASE + 8)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOVU_U8 (SLJIT_OP1_BASE + 9)
+#define SLJIT_MOVU32_U8 (SLJIT_MOVU_U8 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOVU_S8 (SLJIT_OP1_BASE + 10)
+#define SLJIT_MOVU32_S8 (SLJIT_MOVU_S8 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOVU_U16 (SLJIT_OP1_BASE + 11)
+#define SLJIT_MOVU32_U16 (SLJIT_MOVU_U16 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOVU_S16 (SLJIT_OP1_BASE + 12)
+#define SLJIT_MOVU32_S16 (SLJIT_MOVU_S16 | SLJIT_I32_OP)
+/* Flags: I - (never set any flags)
+ Note: no SLJIT_MOVU32_U32 form, since it is the same as SLJIT_MOVU32 */
+#define SLJIT_MOVU_U32 (SLJIT_OP1_BASE + 13)
+/* Flags: I - (never set any flags)
+ Note: no SLJIT_MOVU32_S32 form, since it is the same as SLJIT_MOVU32 */
+#define SLJIT_MOVU_S32 (SLJIT_OP1_BASE + 14)
+/* Flags: I - (never set any flags) */
+#define SLJIT_MOVU32 (SLJIT_MOVU_S32 | SLJIT_I32_OP)
+/* Flags: - (never set any flags) */
+#define SLJIT_MOVU_P (SLJIT_OP1_BASE + 15)
+/* Flags: I | E | K */
+#define SLJIT_NOT (SLJIT_OP1_BASE + 16)
+#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_I32_OP)
+/* Flags: I | E | O | K */
+#define SLJIT_NEG (SLJIT_OP1_BASE + 17)
+#define SLJIT_NEG32 (SLJIT_NEG | SLJIT_I32_OP)
+/* Count leading zeroes
+ Flags: I | E | K
+ Important note! Sparc 32 does not support K flag, since
+ the required popc instruction is introduced only in sparc 64. */
+#define SLJIT_CLZ (SLJIT_OP1_BASE + 18)
+#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_I32_OP)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw);
+
+/* Starting index of opcodes for sljit_emit_op2. */
+#define SLJIT_OP2_BASE 96
+
+/* Flags: I | E | O | C | K */
+#define SLJIT_ADD (SLJIT_OP2_BASE + 0)
+#define SLJIT_ADD32 (SLJIT_ADD | SLJIT_I32_OP)
+/* Flags: I | C | K */
+#define SLJIT_ADDC (SLJIT_OP2_BASE + 1)
+#define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_I32_OP)
+/* Flags: I | E | U | S | O | C | K */
+#define SLJIT_SUB (SLJIT_OP2_BASE + 2)
+#define SLJIT_SUB32 (SLJIT_SUB | SLJIT_I32_OP)
+/* Flags: I | C | K */
+#define SLJIT_SUBC (SLJIT_OP2_BASE + 3)
+#define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_I32_OP)
+/* Note: integer mul
+ Flags: I | O (see SLJIT_C_MUL_*) | K */
+#define SLJIT_MUL (SLJIT_OP2_BASE + 4)
+#define SLJIT_MUL32 (SLJIT_MUL | SLJIT_I32_OP)
+/* Flags: I | E | K */
+#define SLJIT_AND (SLJIT_OP2_BASE + 5)
+#define SLJIT_AND32 (SLJIT_AND | SLJIT_I32_OP)
+/* Flags: I | E | K */
+#define SLJIT_OR (SLJIT_OP2_BASE + 6)
+#define SLJIT_OR32 (SLJIT_OR | SLJIT_I32_OP)
+/* Flags: I | E | K */
+#define SLJIT_XOR (SLJIT_OP2_BASE + 7)
+#define SLJIT_XOR32 (SLJIT_XOR | SLJIT_I32_OP)
+/* Flags: I | E | K
+ Let bit_length be the length of the shift operation: 32 or 64.
+ If src2 is immediate, src2w is masked by (bit_length - 1).
+ Otherwise, if the content of src2 is outside the range from 0
+ to bit_length - 1, the result is undefined. */
+#define SLJIT_SHL (SLJIT_OP2_BASE + 8)
+#define SLJIT_SHL32 (SLJIT_SHL | SLJIT_I32_OP)
+/* Flags: I | E | K
+ Let bit_length be the length of the shift operation: 32 or 64.
+ If src2 is immediate, src2w is masked by (bit_length - 1).
+ Otherwise, if the content of src2 is outside the range from 0
+ to bit_length - 1, the result is undefined. */
+#define SLJIT_LSHR (SLJIT_OP2_BASE + 9)
+#define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_I32_OP)
+/* Flags: I | E | K
+ Let bit_length be the length of the shift operation: 32 or 64.
+ If src2 is immediate, src2w is masked by (bit_length - 1).
+ Otherwise, if the content of src2 is outside the range from 0
+ to bit_length - 1, the result is undefined. */
+#define SLJIT_ASHR (SLJIT_OP2_BASE + 10)
+#define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_I32_OP)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+/* Returns with non-zero if fpu is available. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void);
+
+/* Starting index of opcodes for sljit_emit_fop1. */
+#define SLJIT_FOP1_BASE 128
+
+/* Flags: SP - (never set any flags) */
+#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0)
+#define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_F32_OP)
+/* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]
+ SRC/DST TYPE can be: D - double, S - single, W - signed word, I - signed int
+ Rounding mode when the destination is W or I: round towards zero. */
+/* Flags: SP - (never set any flags) */
+#define SLJIT_CONV_F64_FROM_F32 (SLJIT_FOP1_BASE + 1)
+#define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_CONV_SW_FROM_F64 (SLJIT_FOP1_BASE + 2)
+#define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_CONV_S32_FROM_F64 (SLJIT_FOP1_BASE + 3)
+#define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_CONV_F64_FROM_SW (SLJIT_FOP1_BASE + 4)
+#define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5)
+#define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_F32_OP)
+/* Note: dst is the left and src is the right operand for SLJIT_CMPD.
+ Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED flag
+ is set, the comparison result is unpredictable.
+ Flags: SP | E | S (see SLJIT_C_FLOAT_*) */
+#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6)
+#define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7)
+#define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8)
+#define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_F32_OP)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw);
+
+/* Starting index of opcodes for sljit_emit_fop2. */
+#define SLJIT_FOP2_BASE 160
+
+/* Flags: SP - (never set any flags) */
+#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0)
+#define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_SUB_F64 (SLJIT_FOP2_BASE + 1)
+#define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_MUL_F64 (SLJIT_FOP2_BASE + 2)
+#define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_F32_OP)
+/* Flags: SP - (never set any flags) */
+#define SLJIT_DIV_F64 (SLJIT_FOP2_BASE + 3)
+#define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_F32_OP)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+/* Label and jump instructions. */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
+
+/* Invert (negate) conditional type: xor (^) with 0x1 */
+
+/* Integer comparison types. */
+#define SLJIT_EQUAL 0
+#define SLJIT_EQUAL32 (SLJIT_EQUAL | SLJIT_I32_OP)
+#define SLJIT_ZERO 0
+#define SLJIT_ZERO32 (SLJIT_ZERO | SLJIT_I32_OP)
+#define SLJIT_NOT_EQUAL 1
+#define SLJIT_NOT_EQUAL32 (SLJIT_NOT_EQUAL | SLJIT_I32_OP)
+#define SLJIT_NOT_ZERO 1
+#define SLJIT_NOT_ZERO32 (SLJIT_NOT_ZERO | SLJIT_I32_OP)
+
+#define SLJIT_LESS 2
+#define SLJIT_LESS32 (SLJIT_LESS | SLJIT_I32_OP)
+#define SLJIT_GREATER_EQUAL 3
+#define SLJIT_GREATER_EQUAL32 (SLJIT_GREATER_EQUAL | SLJIT_I32_OP)
+#define SLJIT_GREATER 4
+#define SLJIT_GREATER32 (SLJIT_GREATER | SLJIT_I32_OP)
+#define SLJIT_LESS_EQUAL 5
+#define SLJIT_LESS_EQUAL32 (SLJIT_LESS_EQUAL | SLJIT_I32_OP)
+#define SLJIT_SIG_LESS 6
+#define SLJIT_SIG_LESS32 (SLJIT_SIG_LESS | SLJIT_I32_OP)
+#define SLJIT_SIG_GREATER_EQUAL 7
+#define SLJIT_SIG_GREATER_EQUAL32 (SLJIT_SIG_GREATER_EQUAL | SLJIT_I32_OP)
+#define SLJIT_SIG_GREATER 8
+#define SLJIT_SIG_GREATER32 (SLJIT_SIG_GREATER | SLJIT_I32_OP)
+#define SLJIT_SIG_LESS_EQUAL 9
+#define SLJIT_SIG_LESS_EQUAL32 (SLJIT_SIG_LESS_EQUAL | SLJIT_I32_OP)
+
+#define SLJIT_OVERFLOW 10
+#define SLJIT_OVERFLOW32 (SLJIT_OVERFLOW | SLJIT_I32_OP)
+#define SLJIT_NOT_OVERFLOW 11
+#define SLJIT_NOT_OVERFLOW32 (SLJIT_NOT_OVERFLOW | SLJIT_I32_OP)
+
+#define SLJIT_MUL_OVERFLOW 12
+#define SLJIT_MUL_OVERFLOW32 (SLJIT_MUL_OVERFLOW | SLJIT_I32_OP)
+#define SLJIT_MUL_NOT_OVERFLOW 13
+#define SLJIT_MUL_NOT_OVERFLOW32 (SLJIT_MUL_NOT_OVERFLOW | SLJIT_I32_OP)
+
+/* Floating point comparison types. */
+#define SLJIT_EQUAL_F64 14
+#define SLJIT_EQUAL_F32 (SLJIT_EQUAL_F64 | SLJIT_F32_OP)
+#define SLJIT_NOT_EQUAL_F64 15
+#define SLJIT_NOT_EQUAL_F32 (SLJIT_NOT_EQUAL_F64 | SLJIT_F32_OP)
+#define SLJIT_LESS_F64 16
+#define SLJIT_LESS_F32 (SLJIT_LESS_F64 | SLJIT_F32_OP)
+#define SLJIT_GREATER_EQUAL_F64 17
+#define SLJIT_GREATER_EQUAL_F32 (SLJIT_GREATER_EQUAL_F64 | SLJIT_F32_OP)
+#define SLJIT_GREATER_F64 18
+#define SLJIT_GREATER_F32 (SLJIT_GREATER_F64 | SLJIT_F32_OP)
+#define SLJIT_LESS_EQUAL_F64 19
+#define SLJIT_LESS_EQUAL_F32 (SLJIT_LESS_EQUAL_F64 | SLJIT_F32_OP)
+#define SLJIT_UNORDERED_F64 20
+#define SLJIT_UNORDERED_F32 (SLJIT_UNORDERED_F64 | SLJIT_F32_OP)
+#define SLJIT_ORDERED_F64 21
+#define SLJIT_ORDERED_F32 (SLJIT_ORDERED_F64 | SLJIT_F32_OP)
+
+/* Unconditional jump types. */
+#define SLJIT_JUMP 22
+#define SLJIT_FAST_CALL 23
+#define SLJIT_CALL0 24
+#define SLJIT_CALL1 25
+#define SLJIT_CALL2 26
+#define SLJIT_CALL3 27
+
+/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
+
+/* The target can be changed during runtime (see: sljit_set_jump_addr). */
+#define SLJIT_REWRITABLE_JUMP 0x1000
+
+/* Emit a jump instruction. The destination is not set, only the type of the jump.
+ type must be between SLJIT_EQUAL and SLJIT_CALL3
+ type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+ Flags: - (never set any flags) for both conditional and unconditional jumps.
+ Flags: destroy all flags for calls. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type);
+
+/* Basic arithmetic comparison. In most architectures it is implemented as
+ an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
+ appropriate flags) followed by a sljit_emit_jump. However some
+ architectures (i.e: ARM64 or MIPS) may employ special optimizations here.
+ It is suggested to use this comparison form when appropriate.
+ type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL
+ type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+ Flags: destroy flags. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+/* Basic floating point comparison. In most architectures it is implemented as
+ an SLJIT_FCMP operation (setting appropriate flags) followed by a
+ sljit_emit_jump. However some architectures (i.e: MIPS) may employ
+ special optimizations here. It is suggested to use this comparison form
+ when appropriate.
+ type must be between SLJIT_EQUAL_F64 and SLJIT_ORDERED_F32
+ type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+ Flags: destroy flags.
+ Note: if either operand is NaN, the behaviour is undefined for
+ types up to SLJIT_S_LESS_EQUAL. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+/* Set the destination of the jump to this label. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
+/* Set the destination address of the jump to this label. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
+
+/* Call function or jump anywhere. Both direct and indirect form
+ type must be between SLJIT_JUMP and SLJIT_CALL3
+ Direct form: set src to SLJIT_IMM() and srcw to the address
+ Indirect form: any other valid addressing mode
+ Flags: - (never set any flags) for unconditional jumps.
+ Flags: destroy all flags for calls. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw);
+
+/* Perform the operation using the conditional flags as the second argument.
+ Type must always be between SLJIT_EQUAL and SLJIT_S_ORDERED. The value
+ represented by the type is 1, if the condition represented by the type
+ is fulfilled, and 0 otherwise.
+
+ If op == SLJIT_MOV, SLJIT_MOV_S32, SLJIT_MOV_U32:
+ Set dst to the value represented by the type (0 or 1).
+ Src must be SLJIT_UNUSED, and srcw must be 0
+ Flags: - (never set any flags)
+ If op == SLJIT_OR, op == SLJIT_AND, op == SLJIT_XOR
+ Performs the binary operation using src as the first, and the value
+ represented by type as the second argument.
+ Important note: only dst=src and dstw=srcw is supported at the moment!
+ Flags: I | E | K
+ Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type);
+
+/* Copies the base address of SLJIT_SP + offset to dst.
+ Flags: - (never set any flags) */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
+
+/* The constant can be changed runtime (see: sljit_set_const)
+ Flags: - (never set any flags) */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
+
+/* After the code generation the address for label, jump and const instructions
+ are computed. Since these structures are freed by sljit_free_compiler, the
+ addresses must be preserved by the user program elsewere. */
+static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
+static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
+static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
+
+/* Only the address and executable offset are required to perform dynamic
+ code modifications. See sljit_get_executable_offset function. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset);
+
+/* --------------------------------------------------------------------- */
+/* Miscellaneous utility functions */
+/* --------------------------------------------------------------------- */
+
+#define SLJIT_MAJOR_VERSION 0
+#define SLJIT_MINOR_VERSION 93
+
+/* Get the human readable name of the platform. Can be useful on platforms
+ like ARM, where ARM and Thumb2 functions can be mixed, and
+ it is useful to know the type of the code generator. */
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);
+
+/* Portable helper function to get an offset of a member. */
+#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+/* This global lock is useful to compile common functions. */
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void);
+#endif
+
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
+
+/* The sljit_stack is a utiliy feature of sljit, which allocates a
+ writable memory region between base (inclusive) and limit (exclusive).
+ Both base and limit is a pointer, and base is always <= than limit.
+ This feature uses the "address space reserve" feature
+ of modern operating systems. Basically we don't need to allocate a
+ huge memory block in one step for the worst case, we can start with
+ a smaller chunk and extend it later. Since the address space is
+ reserved, the data never copied to other regions, thus it is safe
+ to store pointers here. */
+
+/* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more).
+ Note: stack growing should not happen in small steps: 4k, 16k or even
+ bigger growth is better.
+ Note: this structure may not be supported by all operating systems.
+ Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK
+ is not defined. */
+
+struct sljit_stack {
+ /* User data, anything can be stored here.
+ Starting with the same value as base. */
+ sljit_uw top;
+ /* These members are read only. */
+ sljit_uw base;
+ sljit_uw limit;
+ sljit_uw max_limit;
+};
+
+/* Returns NULL if unsuccessful.
+ Note: limit and max_limit contains the size for stack allocation.
+ Note: the top field is initialized to base.
+ Note: see sljit_create_compiler for the explanation of allocator_data. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
+
+/* Can be used to increase (allocate) or decrease (free) the memory area.
+ Returns with a non-zero value if unsuccessful. If new_limit is greater than
+ max_limit, it will fail. It is very easy to implement a stack data structure,
+ since the growth ratio can be added to the current limit, and sljit_stack_resize
+ will do all the necessary checks. The fields of the stack are not changed if
+ sljit_stack_resize fails. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack *stack, sljit_uw new_limit);
+
+#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
+
+#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+
+/* Get the entry address of a given function. */
+#define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)func_name)
+
+#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
+
+/* All JIT related code should be placed in the same context (library, binary, etc.). */
+
+#define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name)
+
+/* For powerpc64, the function pointers point to a context descriptor. */
+struct sljit_function_context {
+ sljit_sw addr;
+ sljit_sw r2;
+ sljit_sw r11;
+};
+
+/* Fill the context arguments using the addr and the function.
+ If func_ptr is NULL, it will not be set to the address of context
+ If addr is NULL, the function address also comes from the func pointer. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func);
+
+#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
+
+/* --------------------------------------------------------------------- */
+/* CPU specific functions */
+/* --------------------------------------------------------------------- */
+
+/* The following function is a helper function for sljit_emit_op_custom.
+ It returns with the real machine register index ( >=0 ) of any SLJIT_R,
+ SLJIT_S and SLJIT_SP registers.
+
+ Note: it returns with -1 for virtual registers (only on x86-32). */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg);
+
+/* The following function is a helper function for sljit_emit_op_custom.
+ It returns with the real machine register index of any SLJIT_FLOAT register.
+
+ Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg);
+
+/* Any instruction can be inserted into the instruction stream by
+ sljit_emit_op_custom. It has a similar purpose as inline assembly.
+ The size parameter must match to the instruction size of the target
+ architecture:
+
+ x86: 0 < size <= 15. The instruction argument can be byte aligned.
+ Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
+ if size == 4, the instruction argument must be 4 byte aligned.
+ Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size);
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+/* Returns with non-zero if sse2 is available. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void);
+
+/* Returns with non-zero if cmov instruction is available. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void);
+
+/* Emit a conditional mov instruction on x86 CPUs. This instruction
+ moves src to destination, if the condition is satisfied. Unlike
+ other arithmetic instructions, destination must be a register.
+ Before such instructions are emitted, cmov support should be
+ checked by sljit_x86_is_cmov_available function.
+ type must be between SLJIT_EQUAL and SLJIT_S_ORDERED
+ dst_reg must be a valid register and it can be combined
+ with SLJIT_I32_OP to perform 32 bit arithmetic
+ Flags: I - (never set any flags)
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler,
+ sljit_s32 type,
+ sljit_s32 dst_reg,
+ sljit_s32 src, sljit_sw srcw);
+
+#endif
+
+#endif /* _SLJIT_LIR_H_ */
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
new file mode 100644
index 0000000000..09701d53fc
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
@@ -0,0 +1,2583 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ return "ARMv7" SLJIT_CPUINFO;
+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ return "ARMv5" SLJIT_CPUINFO;
+#else
+#error "Internal error: Unknown ARM architecture"
+#endif
+}
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5)
+
+#define TMP_FREG1 (0)
+#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+
+/* In ARM instruction words.
+ Cache lines are usually 32 byte aligned. */
+#define CONST_POOL_ALIGNMENT 8
+#define CONST_POOL_EMPTY 0xffffffff
+
+#define ALIGN_INSTRUCTION(ptr) \
+ (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1))
+#define MAX_DIFFERENCE(max_diff) \
+ (((max_diff) / (sljit_s32)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
+
+/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
+ 0, 0, 1, 2, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 12, 14, 15
+};
+
+#define RM(rm) (reg_map[rm])
+#define RD(rd) (reg_map[rd] << 12)
+#define RN(rn) (reg_map[rn] << 16)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+/* The instruction includes the AL condition.
+ INST_NAME - CONDITIONAL remove this flag. */
+#define COND_MASK 0xf0000000
+#define CONDITIONAL 0xe0000000
+#define PUSH_POOL 0xff000000
+
+/* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */
+#define ADC_DP 0x5
+#define ADD_DP 0x4
+#define AND_DP 0x0
+#define B 0xea000000
+#define BIC_DP 0xe
+#define BL 0xeb000000
+#define BLX 0xe12fff30
+#define BX 0xe12fff10
+#define CLZ 0xe16f0f10
+#define CMP_DP 0xa
+#define BKPT 0xe1200070
+#define EOR_DP 0x1
+#define MOV_DP 0xd
+#define MUL 0xe0000090
+#define MVN_DP 0xf
+#define NOP 0xe1a00000
+#define ORR_DP 0xc
+#define PUSH 0xe92d0000
+#define POP 0xe8bd0000
+#define RSB_DP 0x3
+#define RSC_DP 0x7
+#define SBC_DP 0x6
+#define SMULL 0xe0c00090
+#define SUB_DP 0x2
+#define UMULL 0xe0800090
+#define VABS_F32 0xeeb00ac0
+#define VADD_F32 0xee300a00
+#define VCMP_F32 0xeeb40a40
+#define VCVT_F32_S32 0xeeb80ac0
+#define VCVT_F64_F32 0xeeb70ac0
+#define VCVT_S32_F32 0xeebd0ac0
+#define VDIV_F32 0xee800a00
+#define VMOV_F32 0xeeb00a40
+#define VMOV 0xee000a10
+#define VMRS 0xeef1fa10
+#define VMUL_F32 0xee200a00
+#define VNEG_F32 0xeeb10a40
+#define VSTR_F32 0xed000a00
+#define VSUB_F32 0xee300a40
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+/* Arm v7 specific instructions. */
+#define MOVW 0xe3000000
+#define MOVT 0xe3400000
+#define SXTB 0xe6af0070
+#define SXTH 0xe6bf0070
+#define UXTB 0xe6ef0070
+#define UXTH 0xe6ff0070
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+
+static sljit_s32 push_cpool(struct sljit_compiler *compiler)
+{
+ /* Pushing the constant pool into the instruction stream. */
+ sljit_uw* inst;
+ sljit_uw* cpool_ptr;
+ sljit_uw* cpool_end;
+ sljit_s32 i;
+
+ /* The label could point the address after the constant pool. */
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1;
+
+ SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE);
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = 0xff000000 | compiler->cpool_fill;
+
+ for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) {
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = 0;
+ }
+
+ cpool_ptr = compiler->cpool;
+ cpool_end = cpool_ptr + compiler->cpool_fill;
+ while (cpool_ptr < cpool_end) {
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = *cpool_ptr++;
+ }
+ compiler->cpool_diff = CONST_POOL_EMPTY;
+ compiler->cpool_fill = 0;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst)
+{
+ sljit_uw* ptr;
+
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
+ FAIL_IF(push_cpool(compiler));
+
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
+{
+ sljit_uw* ptr;
+ sljit_uw cpool_index = CPOOL_SIZE;
+ sljit_uw* cpool_ptr;
+ sljit_uw* cpool_end;
+ sljit_u8* cpool_unique_ptr;
+
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
+ FAIL_IF(push_cpool(compiler));
+ else if (compiler->cpool_fill > 0) {
+ cpool_ptr = compiler->cpool;
+ cpool_end = cpool_ptr + compiler->cpool_fill;
+ cpool_unique_ptr = compiler->cpool_unique;
+ do {
+ if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) {
+ cpool_index = cpool_ptr - compiler->cpool;
+ break;
+ }
+ cpool_ptr++;
+ cpool_unique_ptr++;
+ } while (cpool_ptr < cpool_end);
+ }
+
+ if (cpool_index == CPOOL_SIZE) {
+ /* Must allocate a new entry in the literal pool. */
+ if (compiler->cpool_fill < CPOOL_SIZE) {
+ cpool_index = compiler->cpool_fill;
+ compiler->cpool_fill++;
+ }
+ else {
+ FAIL_IF(push_cpool(compiler));
+ cpool_index = 0;
+ compiler->cpool_fill = 1;
+ }
+ }
+
+ SLJIT_ASSERT((inst & 0xfff) == 0);
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst | cpool_index;
+
+ compiler->cpool[cpool_index] = literal;
+ compiler->cpool_unique[cpool_index] = 0;
+ if (compiler->cpool_diff == CONST_POOL_EMPTY)
+ compiler->cpool_diff = compiler->size;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
+{
+ sljit_uw* ptr;
+ if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))
+ FAIL_IF(push_cpool(compiler));
+
+ SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0);
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst | compiler->cpool_fill;
+
+ compiler->cpool[compiler->cpool_fill] = literal;
+ compiler->cpool_unique[compiler->cpool_fill] = 1;
+ compiler->cpool_fill++;
+ if (compiler->cpool_diff == CONST_POOL_EMPTY)
+ compiler->cpool_diff = compiler->size;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 prepare_blx(struct sljit_compiler *compiler)
+{
+ /* Place for at least two instruction (doesn't matter whether the first has a literal). */
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))
+ return push_cpool(compiler);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_blx(struct sljit_compiler *compiler)
+{
+ /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */
+ SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));
+ return push_inst(compiler, BLX | RM(TMP_REG1));
+}
+
+static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size)
+{
+ sljit_uw diff;
+ sljit_uw ind;
+ sljit_uw counter = 0;
+ sljit_uw* clear_const_pool = const_pool;
+ sljit_uw* clear_const_pool_end = const_pool + cpool_size;
+
+ SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT);
+ /* Set unused flag for all literals in the constant pool.
+ I.e.: unused literals can belong to branches, which can be encoded as B or BL.
+ We can "compress" the constant pool by discarding these literals. */
+ while (clear_const_pool < clear_const_pool_end)
+ *clear_const_pool++ = (sljit_uw)(-1);
+
+ while (last_pc_patch < code_ptr) {
+ /* Data transfer instruction with Rn == r15. */
+ if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) {
+ diff = const_pool - last_pc_patch;
+ ind = (*last_pc_patch) & 0xfff;
+
+ /* Must be a load instruction with immediate offset. */
+ SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));
+ if ((sljit_s32)const_pool[ind] < 0) {
+ const_pool[ind] = counter;
+ ind = counter;
+ counter++;
+ }
+ else
+ ind = const_pool[ind];
+
+ SLJIT_ASSERT(diff >= 1);
+ if (diff >= 2 || ind > 0) {
+ diff = (diff + ind - 2) << 2;
+ SLJIT_ASSERT(diff <= 0xfff);
+ *last_pc_patch = (*last_pc_patch & ~0xfff) | diff;
+ }
+ else
+ *last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004;
+ }
+ last_pc_patch++;
+ }
+ return counter;
+}
+
+/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */
+struct future_patch {
+ struct future_patch* next;
+ sljit_s32 index;
+ sljit_s32 value;
+};
+
+static sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)
+{
+ sljit_s32 value;
+ struct future_patch *curr_patch, *prev_patch;
+
+ SLJIT_UNUSED_ARG(compiler);
+
+ /* Using the values generated by patch_pc_relative_loads. */
+ if (!*first_patch)
+ value = (sljit_s32)cpool_start_address[cpool_current_index];
+ else {
+ curr_patch = *first_patch;
+ prev_patch = NULL;
+ while (1) {
+ if (!curr_patch) {
+ value = (sljit_s32)cpool_start_address[cpool_current_index];
+ break;
+ }
+ if ((sljit_uw)curr_patch->index == cpool_current_index) {
+ value = curr_patch->value;
+ if (prev_patch)
+ prev_patch->next = curr_patch->next;
+ else
+ *first_patch = curr_patch->next;
+ SLJIT_FREE(curr_patch, compiler->allocator_data);
+ break;
+ }
+ prev_patch = curr_patch;
+ curr_patch = curr_patch->next;
+ }
+ }
+
+ if (value >= 0) {
+ if ((sljit_uw)value > cpool_current_index) {
+ curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch), compiler->allocator_data);
+ if (!curr_patch) {
+ while (*first_patch) {
+ curr_patch = *first_patch;
+ *first_patch = (*first_patch)->next;
+ SLJIT_FREE(curr_patch, compiler->allocator_data);
+ }
+ return SLJIT_ERR_ALLOC_FAILED;
+ }
+ curr_patch->next = *first_patch;
+ curr_patch->index = value;
+ curr_patch->value = cpool_start_address[value];
+ *first_patch = curr_patch;
+ }
+ cpool_start_address[value] = *buf_ptr;
+ }
+ return SLJIT_SUCCESS;
+}
+
+#else
+
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst)
+{
+ sljit_uw* ptr;
+
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
+{
+ FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));
+ return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));
+}
+
+#endif
+
+static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code, sljit_sw executable_offset)
+{
+ sljit_sw diff;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (jump->flags & IS_BL)
+ code_ptr--;
+
+ if (jump->flags & JUMP_ADDR)
+ diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset);
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2));
+ }
+
+ /* Branch to Thumb code has not been optimized yet. */
+ if (diff & 0x3)
+ return 0;
+
+ if (jump->flags & IS_BL) {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK);
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ }
+ else {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK);
+ jump->flags |= PATCH_B;
+ }
+ }
+#else
+ if (jump->flags & JUMP_ADDR)
+ diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset);
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr);
+ }
+
+ /* Branch to Thumb code has not been optimized yet. */
+ if (diff & 0x3)
+ return 0;
+
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ code_ptr -= 2;
+ *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK);
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache)
+{
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw *ptr = (sljit_uw *)jump_ptr;
+ sljit_uw *inst = (sljit_uw *)ptr[0];
+ sljit_uw mov_pc = ptr[1];
+ sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
+ sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);
+
+ if (diff <= 0x7fffff && diff >= -0x800000) {
+ /* Turn to branch. */
+ if (!bl) {
+ inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ } else {
+ inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
+ inst[1] = NOP;
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+ }
+ } else {
+ /* Get the position of the constant. */
+ if (mov_pc & (1 << 23))
+ ptr = inst + ((mov_pc & 0xfff) >> 2) + 2;
+ else
+ ptr = inst + 1;
+
+ if (*inst != mov_pc) {
+ inst[0] = mov_pc;
+ if (!bl) {
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ } else {
+ inst[1] = BLX | RM(TMP_REG1);
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+ }
+ }
+ *ptr = new_addr;
+ }
+#else
+ sljit_uw *inst = (sljit_uw*)jump_ptr;
+ SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+ inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
+ inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+#endif
+}
+
+static sljit_uw get_imm(sljit_uw imm);
+
+static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_sw new_constant, sljit_s32 flush_cache)
+{
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw *ptr = (sljit_uw*)addr;
+ sljit_uw *inst = (sljit_uw*)ptr[0];
+ sljit_uw ldr_literal = ptr[1];
+ sljit_uw src2;
+
+ src2 = get_imm(new_constant);
+ if (src2) {
+ *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ return;
+ }
+
+ src2 = get_imm(~new_constant);
+ if (src2) {
+ *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ return;
+ }
+
+ if (ldr_literal & (1 << 23))
+ ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2;
+ else
+ ptr = inst + 1;
+
+ if (*inst != ldr_literal) {
+ *inst = ldr_literal;
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ }
+ *ptr = new_constant;
+#else
+ sljit_uw *inst = (sljit_uw*)addr;
+ SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+ inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
+ inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
+ if (flush_cache) {
+ inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_uw *code;
+ sljit_uw *code_ptr;
+ sljit_uw *buf_ptr;
+ sljit_uw *buf_end;
+ sljit_uw size;
+ sljit_uw word_count;
+ sljit_sw executable_offset;
+ sljit_sw jump_addr;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw cpool_size;
+ sljit_uw cpool_skip_alignment;
+ sljit_uw cpool_current_index;
+ sljit_uw *cpool_start_address;
+ sljit_uw *last_pc_patch;
+ struct future_patch *first_patch;
+#endif
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ /* Second code generation pass. */
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ size = compiler->size + (compiler->patches << 1);
+ if (compiler->cpool_fill > 0)
+ size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;
+#else
+ size = compiler->size;
+#endif
+ code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ cpool_size = 0;
+ cpool_skip_alignment = 0;
+ cpool_current_index = 0;
+ cpool_start_address = NULL;
+ first_patch = NULL;
+ last_pc_patch = code;
+#endif
+
+ code_ptr = code;
+ word_count = 0;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ if (label && label->size == 0) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ label = label->next;
+ }
+
+ do {
+ buf_ptr = (sljit_uw*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ word_count++;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (cpool_size > 0) {
+ if (cpool_skip_alignment > 0) {
+ buf_ptr++;
+ cpool_skip_alignment--;
+ }
+ else {
+ if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
+ SLJIT_FREE_EXEC(code);
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+ return NULL;
+ }
+ buf_ptr++;
+ if (++cpool_current_index >= cpool_size) {
+ SLJIT_ASSERT(!first_patch);
+ cpool_size = 0;
+ if (label && label->size == word_count) {
+ /* Points after the current instruction. */
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ }
+ }
+ }
+ else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
+#endif
+ *code_ptr = *buf_ptr++;
+ /* These structures are ordered by their address. */
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (detect_jump_type(jump, code_ptr, code, executable_offset))
+ code_ptr--;
+ jump->addr = (sljit_uw)code_ptr;
+#else
+ jump->addr = (sljit_uw)(code_ptr - 2);
+ if (detect_jump_type(jump, code_ptr, code, executable_offset))
+ code_ptr -= 2;
+#endif
+ jump = jump->next;
+ }
+ if (label && label->size == word_count) {
+ /* code_ptr can be affected above. */
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);
+ label->size = (code_ptr + 1) - code;
+ label = label->next;
+ }
+ if (const_ && const_->addr == word_count) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ const_->addr = (sljit_uw)code_ptr;
+#else
+ const_->addr = (sljit_uw)(code_ptr - 1);
+#endif
+ const_ = const_->next;
+ }
+ code_ptr++;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ }
+ else {
+ /* Fortunately, no need to shift. */
+ cpool_size = *buf_ptr++ & ~PUSH_POOL;
+ SLJIT_ASSERT(cpool_size > 0);
+ cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1);
+ cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size);
+ if (cpool_current_index > 0) {
+ /* Unconditional branch. */
+ *code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL);
+ code_ptr = cpool_start_address + cpool_current_index;
+ }
+ cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1;
+ cpool_current_index = 0;
+ last_pc_patch = code_ptr;
+ }
+#endif
+ } while (buf_ptr < buf_end);
+ buf = buf->next;
+ } while (buf);
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ SLJIT_ASSERT(cpool_size == 0);
+ if (compiler->cpool_fill > 0) {
+ cpool_start_address = ALIGN_INSTRUCTION(code_ptr);
+ cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill);
+ if (cpool_current_index > 0)
+ code_ptr = cpool_start_address + cpool_current_index;
+
+ buf_ptr = compiler->cpool;
+ buf_end = buf_ptr + compiler->cpool_fill;
+ cpool_current_index = 0;
+ while (buf_ptr < buf_end) {
+ if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
+ SLJIT_FREE_EXEC(code);
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+ return NULL;
+ }
+ buf_ptr++;
+ cpool_current_index++;
+ }
+ SLJIT_ASSERT(!first_patch);
+ }
+#endif
+
+ jump = compiler->jumps;
+ while (jump) {
+ buf_ptr = (sljit_uw *)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
+ if (!(jump->flags & JUMP_ADDR)) {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000);
+ *buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff;
+ }
+ else {
+ SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000);
+ *buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff;
+ }
+ }
+ else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ jump->addr = (sljit_uw)code_ptr;
+ code_ptr[0] = (sljit_uw)buf_ptr;
+ code_ptr[1] = *buf_ptr;
+ inline_set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+ code_ptr += 2;
+#else
+ inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+#endif
+ }
+ else {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (jump->flags & IS_BL)
+ buf_ptr--;
+ if (*buf_ptr & (1 << 23))
+ buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+ else
+ buf_ptr += 1;
+ *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+#else
+ inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+#endif
+ }
+ jump = jump->next;
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ const_ = compiler->consts;
+ while (const_) {
+ buf_ptr = (sljit_uw*)const_->addr;
+ const_->addr = (sljit_uw)code_ptr;
+
+ code_ptr[0] = (sljit_uw)buf_ptr;
+ code_ptr[1] = *buf_ptr;
+ if (*buf_ptr & (1 << 23))
+ buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+ else
+ buf_ptr += 1;
+ /* Set the value again (can be a simple constant). */
+ inline_set_const((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
+ code_ptr += 2;
+
+ const_ = const_->next;
+ }
+#endif
+
+ SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw);
+
+ code = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ return code;
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+/* emit_op inp_flags.
+ WRITE_BACK must be the first, since it is a flag. */
+#define WRITE_BACK 0x01
+#define ALLOW_IMM 0x02
+#define ALLOW_INV_IMM 0x04
+#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM)
+#define ARG_TEST 0x08
+
+/* Creates an index in data_transfer_insts array. */
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x10
+#define HALF_DATA 0x20
+#define SIGNED_DATA 0x40
+#define LOAD_DATA 0x80
+
+/* Condition: AL. */
+#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \
+ (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2))
+
+static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 size, i, tmp;
+ sljit_uw push;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ /* Push saved registers, temporary registers
+ stmdb sp!, {..., lr} */
+ push = PUSH | (1 << 14);
+
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--)
+ push |= 1 << reg_map[i];
+
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
+ push |= 1 << reg_map[i];
+
+ FAIL_IF(push_inst(compiler, push));
+
+ /* Stack must be aligned to 8 bytes: */
+ size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
+ local_size = ((size + local_size + 7) & ~7) - size;
+ compiler->local_size = local_size;
+ if (local_size > 0)
+ FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size));
+
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S0, SLJIT_UNUSED, RM(SLJIT_R0))));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S1, SLJIT_UNUSED, RM(SLJIT_R1))));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S2, SLJIT_UNUSED, RM(SLJIT_R2))));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 size;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
+ compiler->local_size = ((size + local_size + 7) & ~7) - size;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 i, tmp;
+ sljit_uw pop;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0)
+ FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
+
+ /* Push saved registers, temporary registers
+ ldmia sp!, {..., pc} */
+ pop = POP | (1 << 15);
+
+ tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--)
+ pop |= 1 << reg_map[i];
+
+ for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
+ pop |= 1 << reg_map[i];
+
+ return push_inst(compiler, pop);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* s/l - store/load (1 bit)
+ u/s - signed/unsigned (1 bit)
+ w/b/h/N - word/byte/half/NOT allowed (2 bit)
+ It contans 16 items, but not all are different. */
+
+static sljit_sw data_transfer_insts[16] = {
+/* s u w */ 0xe5000000 /* str */,
+/* s u b */ 0xe5400000 /* strb */,
+/* s u h */ 0xe10000b0 /* strh */,
+/* s u N */ 0x00000000 /* not allowed */,
+/* s s w */ 0xe5000000 /* str */,
+/* s s b */ 0xe5400000 /* strb */,
+/* s s h */ 0xe10000b0 /* strh */,
+/* s s N */ 0x00000000 /* not allowed */,
+
+/* l u w */ 0xe5100000 /* ldr */,
+/* l u b */ 0xe5500000 /* ldrb */,
+/* l u h */ 0xe11000b0 /* ldrh */,
+/* l u N */ 0x00000000 /* not allowed */,
+/* l s w */ 0xe5100000 /* ldr */,
+/* l s b */ 0xe11000d0 /* ldrsb */,
+/* l s h */ 0xe11000f0 /* ldrsh */,
+/* l s N */ 0x00000000 /* not allowed */,
+};
+
+#define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \
+ (data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2))
+/* Normal ldr/str instruction.
+ Type2: ldrsb, ldrh, ldrsh */
+#define IS_TYPE1_TRANSFER(type) \
+ (data_transfer_insts[(type) >> 4] & 0x04000000)
+#define TYPE2_TRANSFER_IMM(imm) \
+ (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22))
+
+/* flags: */
+ /* Arguments are swapped. */
+#define ARGS_SWAPPED 0x01
+ /* Inverted immediate. */
+#define INV_IMM 0x02
+ /* Source and destination is register. */
+#define REG_DEST 0x04
+#define REG_SOURCE 0x08
+ /* One instruction is enough. */
+#define FAST_DEST 0x10
+ /* Multiple instructions are required. */
+#define SLOW_DEST 0x20
+/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */
+#define SET_FLAGS (1 << 20)
+/* dst: reg
+ src1: reg
+ src2: reg or imm (if allowed)
+ SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */
+#define SRC2_IMM (1 << 25)
+
+#define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2)))
+
+#define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2))
+
+#define EMIT_SHIFT_INS_AND_RETURN(opcode) \
+ SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \
+ if (compiler->shift_imm != 0x20) { \
+ SLJIT_ASSERT(src1 == TMP_REG1); \
+ SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \
+ if (compiler->shift_imm != 0) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \
+ } \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));
+
+static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
+{
+ sljit_sw mul_inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if (dst != src2) {
+ if (src2 & SRC2_IMM) {
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (op == SLJIT_MOV_U8)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff));
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2])));
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | reg_map[dst]));
+#else
+ return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2));
+#endif
+ }
+ else if (dst != src2) {
+ SLJIT_ASSERT(src2 & SRC2_IMM);
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2])));
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | reg_map[dst]));
+#else
+ return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2));
+#endif
+ }
+ else if (dst != src2) {
+ SLJIT_ASSERT(src2 & SRC2_IMM);
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ if (src2 & SRC2_IMM) {
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ }
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ SLJIT_ASSERT(!(src2 & SRC2_IMM));
+ FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2)));
+ if (flags & SET_FLAGS)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ADD:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP);
+
+ case SLJIT_ADDC:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP);
+
+ case SLJIT_SUB:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ if (!(flags & ARGS_SWAPPED))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP);
+
+ case SLJIT_SUBC:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ if (!(flags & ARGS_SWAPPED))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP);
+
+ case SLJIT_MUL:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ SLJIT_ASSERT(!(src2 & SRC2_IMM));
+ if (SLJIT_UNLIKELY(op & SLJIT_SET_O))
+ mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12);
+ else
+ mul_inst = MUL | (reg_map[dst] << 16);
+
+ if (dst != src2)
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2]));
+ else if (dst != src1)
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1]));
+ else {
+ /* Rm and Rd must not be the same register. */
+ SLJIT_ASSERT(dst != TMP_REG1);
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2])));
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1]));
+ }
+
+ if (!(op & SLJIT_SET_O))
+ return SLJIT_SUCCESS;
+
+ /* We need to use TMP_REG3. */
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ /* cmp TMP_REG2, dst asr #31. */
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0));
+
+ case SLJIT_AND:
+ if (!(flags & INV_IMM))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP);
+
+ case SLJIT_OR:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP);
+
+ case SLJIT_XOR:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP);
+
+ case SLJIT_SHL:
+ EMIT_SHIFT_INS_AND_RETURN(0);
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT_INS_AND_RETURN(1);
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT_INS_AND_RETURN(2);
+ }
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+#undef EMIT_DATA_PROCESS_INS_AND_RETURN
+#undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN
+#undef EMIT_SHIFT_INS_AND_RETURN
+
+/* Tests whether the immediate can be stored in the 12 bit imm field.
+ Returns with 0 if not possible. */
+static sljit_uw get_imm(sljit_uw imm)
+{
+ sljit_s32 rol;
+
+ if (imm <= 0xff)
+ return SRC2_IMM | imm;
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol = 8;
+ }
+ else {
+ imm = (imm << 24) | (imm >> 8);
+ rol = 0;
+ }
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol += 4;
+ }
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ return SRC2_IMM | (imm >> 24) | (rol << 8);
+ else
+ return 0;
+}
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm, sljit_s32 positive)
+{
+ sljit_uw mask;
+ sljit_uw imm1;
+ sljit_uw imm2;
+ sljit_s32 rol;
+
+ /* Step1: Search a zero byte (8 continous zero bit). */
+ mask = 0xff000000;
+ rol = 8;
+ while(1) {
+ if (!(imm & mask)) {
+ /* Rol imm by rol. */
+ imm = (imm << rol) | (imm >> (32 - rol));
+ /* Calculate arm rol. */
+ rol = 4 + (rol >> 1);
+ break;
+ }
+ rol += 2;
+ mask >>= 2;
+ if (mask & 0x3) {
+ /* rol by 8. */
+ imm = (imm << 8) | (imm >> 24);
+ mask = 0xff00;
+ rol = 24;
+ while (1) {
+ if (!(imm & mask)) {
+ /* Rol imm by rol. */
+ imm = (imm << rol) | (imm >> (32 - rol));
+ /* Calculate arm rol. */
+ rol = (rol >> 1) - 8;
+ break;
+ }
+ rol += 2;
+ mask >>= 2;
+ if (mask & 0x3)
+ return 0;
+ }
+ break;
+ }
+ }
+
+ /* The low 8 bit must be zero. */
+ SLJIT_ASSERT(!(imm & 0xff));
+
+ if (!(imm & 0xff000000)) {
+ imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
+ imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
+ }
+ else if (imm & 0xc0000000) {
+ imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm <<= 8;
+ rol += 4;
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol += 4;
+ }
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ else
+ return 0;
+ }
+ else {
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm <<= 8;
+ rol += 4;
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ else
+ return 0;
+ }
+
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1)));
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2)));
+ return 1;
+}
+#endif
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm)
+{
+ sljit_uw tmp;
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff));
+#endif
+
+ /* Create imm by 1 inst. */
+ tmp = get_imm(imm);
+ if (tmp)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));
+
+ tmp = get_imm(~imm);
+ if (tmp)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ /* Create imm by 2 inst. */
+ FAIL_IF(generate_int(compiler, reg, imm, 1));
+ FAIL_IF(generate_int(compiler, reg, ~imm, 0));
+
+ /* Load integer. */
+ return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm);
+#else
+ return emit_imm(compiler, reg, imm);
+#endif
+}
+
+/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
+static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
+{
+ if (value >= 0) {
+ value = get_imm(value);
+ if (value)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value));
+ }
+ else {
+ value = get_imm(-value);
+ if (value)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value));
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+/* Can perform an operation using at most 1 instruction. */
+static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ sljit_uw imm;
+
+ if (arg & SLJIT_IMM) {
+ imm = get_imm(argw);
+ if (imm) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm)));
+ return -1;
+ }
+ imm = get_imm(~argw);
+ if (imm) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm)));
+ return -1;
+ }
+ return 0;
+ }
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads/stores. */
+ if (!(arg & REG_MASK))
+ return 0;
+
+ if (arg & OFFS_REG_MASK) {
+ if ((argw & 0x3) != 0 && !IS_TYPE1_TRANSFER(inp_flags))
+ return 0;
+
+ if (inp_flags & ARG_TEST)
+ return 1;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK,
+ RM(OFFS_REG(arg)) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7))));
+ return -1;
+ }
+
+ if (IS_TYPE1_TRANSFER(inp_flags)) {
+ if (argw >= 0 && argw <= 0xfff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, argw)));
+ return -1;
+ }
+ if (argw < 0 && argw >= -0xfff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, -argw)));
+ return -1;
+ }
+ }
+ else {
+ if (argw >= 0 && argw <= 0xff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw))));
+ return -1;
+ }
+ if (argw < 0 && argw >= -0xff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ argw = -argw;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw))));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ /* Immediate caching is not supported as it would be an operation on constant arguments. */
+ if (arg & SLJIT_IMM)
+ return 0;
+
+ /* Always a simple operation. */
+ if (arg & OFFS_REG_MASK)
+ return 0;
+
+ if (!(arg & REG_MASK)) {
+ /* Immediate access. */
+ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
+ return 1;
+ return 0;
+ }
+
+ if (argw <= 0xfffff && argw >= -0xfffff)
+ return 0;
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM))
+ return 1;
+
+ if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
+ return 1;
+
+ return 0;
+}
+
+#define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \
+ if (max_delta & 0xf00) \
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \
+ else \
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm))));
+
+#define TEST_WRITE_BACK() \
+ if (inp_flags & WRITE_BACK) { \
+ tmp_r = arg & REG_MASK; \
+ if (reg == tmp_r) { \
+ /* This can only happen for stores */ \
+ /* since ldr reg, [reg, ...]! has no meaning */ \
+ SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg)))); \
+ reg = TMP_REG3; \
+ } \
+ }
+
+/* Emit the necessary instructions. See can_cache above. */
+static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_s32 tmp_r;
+ sljit_sw max_delta;
+ sljit_sw sign;
+ sljit_uw imm;
+
+ if (arg & SLJIT_IMM) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ return load_immediate(compiler, reg, argw);
+ }
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3;
+ max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff;
+
+ if ((arg & REG_MASK) == SLJIT_UNUSED) {
+ /* Write back is not used. */
+ imm = (sljit_uw)(argw - compiler->cache_argw);
+ if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
+ if (imm <= (sljit_uw)max_delta) {
+ sign = 1;
+ argw = argw - compiler->cache_argw;
+ }
+ else {
+ sign = 0;
+ argw = compiler->cache_argw - argw;
+ }
+
+ GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, argw);
+ return SLJIT_SUCCESS;
+ }
+
+ /* With write back, we can create some sophisticated loads, but
+ it is hard to decide whether we should convert downward (0s) or upward (1s). */
+ imm = (sljit_uw)(argw - next_argw);
+ if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ if (arg & OFFS_REG_MASK) {
+ SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00));
+ if (inp_flags & WRITE_BACK)
+ tmp_r = arg & REG_MASK;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))));
+ return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0)));
+ }
+
+ imm = (sljit_uw)(argw - compiler->cache_argw);
+ if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm);
+ return SLJIT_SUCCESS;
+ }
+ if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ imm = (sljit_uw)-(sljit_sw)imm;
+ GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm);
+ return SLJIT_SUCCESS;
+ }
+
+ imm = get_imm(argw & ~max_delta);
+ if (imm) {
+ TEST_WRITE_BACK();
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, imm)));
+ GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
+ return SLJIT_SUCCESS;
+ }
+
+ imm = get_imm(-argw & ~max_delta);
+ if (imm) {
+ argw = -argw;
+ TEST_WRITE_BACK();
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & REG_MASK, imm)));
+ GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
+ return SLJIT_SUCCESS;
+ }
+
+ if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
+ TEST_WRITE_BACK();
+ return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ }
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+
+ TEST_WRITE_BACK();
+ return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ }
+
+ imm = (sljit_uw)(argw - next_argw);
+ if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & REG_MASK])));
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ if ((arg & REG_MASK) == tmp_r) {
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ return compiler->error;
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+}
+
+static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+
+ /* We prefers register and simple consts. */
+ sljit_s32 dst_r;
+ sljit_s32 src1_r;
+ sljit_s32 src2_r = 0;
+ sljit_s32 sugg_src2_r = TMP_REG2;
+ sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ /* Destination check. */
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ dst_r = TMP_REG2;
+ }
+ else if (FAST_IS_REG(dst)) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ sugg_src2_r = dst_r;
+ }
+ else {
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
+ flags |= FAST_DEST;
+ dst_r = TMP_REG2;
+ }
+ else {
+ flags |= SLOW_DEST;
+ dst_r = 0;
+ }
+ }
+
+ /* Source 1. */
+ if (FAST_IS_REG(src1))
+ src1_r = src1;
+ else if (FAST_IS_REG(src2)) {
+ flags |= ARGS_SWAPPED;
+ src1_r = src2;
+ src2 = src1;
+ src2w = src1w;
+ }
+ else do { /* do { } while(0) is used because of breaks. */
+ src1_r = 0;
+ if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) {
+ /* The second check will generate a hit. */
+ src2_r = get_imm(src1w);
+ if (src2_r) {
+ flags |= ARGS_SWAPPED;
+ src1 = src2;
+ src1w = src2w;
+ break;
+ }
+ if (inp_flags & ALLOW_INV_IMM) {
+ src2_r = get_imm(~src1w);
+ if (src2_r) {
+ flags |= ARGS_SWAPPED | INV_IMM;
+ src1 = src2;
+ src1w = src2w;
+ break;
+ }
+ }
+ if (GET_OPCODE(op) == SLJIT_ADD) {
+ src2_r = get_imm(-src1w);
+ if (src2_r) {
+ /* Note: ARGS_SWAPPED is intentionally not applied! */
+ src1 = src2;
+ src1w = src2w;
+ op = SLJIT_SUB | GET_ALL_FLAGS(op);
+ break;
+ }
+ }
+ }
+
+ if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1_r = TMP_REG1;
+ }
+ } while (0);
+
+ /* Source 2. */
+ if (src2_r == 0) {
+ if (FAST_IS_REG(src2)) {
+ src2_r = src2;
+ flags |= REG_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ dst_r = src2_r;
+ }
+ else do { /* do { } while(0) is used because of breaks. */
+ if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) {
+ src2_r = get_imm(src2w);
+ if (src2_r)
+ break;
+ if (inp_flags & ALLOW_INV_IMM) {
+ src2_r = get_imm(~src2w);
+ if (src2_r) {
+ flags |= INV_IMM;
+ break;
+ }
+ }
+ if (GET_OPCODE(op) == SLJIT_ADD) {
+ src2_r = get_imm(-src2w);
+ if (src2_r) {
+ op = SLJIT_SUB | GET_ALL_FLAGS(op);
+ flags &= ~ARGS_SWAPPED;
+ break;
+ }
+ }
+ if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) {
+ src2_r = get_imm(-src2w);
+ if (src2_r) {
+ op = SLJIT_ADD | GET_ALL_FLAGS(op);
+ flags &= ~ARGS_SWAPPED;
+ break;
+ }
+ }
+ }
+
+ /* src2_r is 0. */
+ if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2_r = sugg_src2_r;
+ }
+ } while (0);
+ }
+
+ /* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero.
+ If they are zero, they must not be registers. */
+ if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ SLJIT_ASSERT(!(flags & ARGS_SWAPPED));
+ flags |= ARGS_SWAPPED;
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ src1_r = TMP_REG1;
+ src2_r = TMP_REG2;
+ }
+ else if (src1_r == 0 && src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ src1_r = TMP_REG1;
+ }
+ else if (src1_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1_r = TMP_REG1;
+ }
+ else if (src2_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+ src2_r = sugg_src2_r;
+ }
+
+ if (dst_r == 0)
+ dst_r = TMP_REG2;
+
+ if (src1_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
+ src1_r = TMP_REG1;
+ }
+
+ if (src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
+ src2_r = sugg_src2_r;
+ }
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (flags & (FAST_DEST | SLOW_DEST)) {
+ if (flags & FAST_DEST)
+ FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw));
+ else
+ FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__)
+extern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator);
+extern int __aeabi_idivmod(int numerator, int denominator);
+#else
+#error "Software divmod functions are needed"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ FAIL_IF(push_inst(compiler, BKPT));
+ break;
+ case SLJIT_NOP:
+ FAIL_IF(push_inst(compiler, NOP));
+ break;
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
+ | (reg_map[SLJIT_R1] << 16)
+ | (reg_map[SLJIT_R0] << 12)
+ | (reg_map[SLJIT_R0] << 8)
+ | reg_map[SLJIT_R1]);
+#else
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_R1))));
+ return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
+ | (reg_map[SLJIT_R1] << 16)
+ | (reg_map[SLJIT_R0] << 12)
+ | (reg_map[SLJIT_R0] << 8)
+ | reg_map[TMP_REG1]);
+#endif
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+ SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
+ SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping);
+
+ if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) {
+ FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */));
+ FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */));
+ }
+ else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3))
+ FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */));
+
+#if defined(__GNUC__)
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
+ ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
+#else
+#error "Software divmod functions are needed"
+#endif
+
+ if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) {
+ FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */));
+ FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */));
+ }
+ else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3))
+ return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */);
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ case SLJIT_MOV_P:
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
+
+ case SLJIT_MOV_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
+
+ case SLJIT_MOV_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
+
+ case SLJIT_MOV_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
+
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_U32:
+ case SLJIT_MOVU_S32:
+ case SLJIT_MOVU_P:
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
+
+ case SLJIT_MOVU_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
+
+ case SLJIT_MOVU_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
+
+ case SLJIT_MOVU_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw);
+
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+ return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+ if (src2 & SLJIT_IMM) {
+ compiler->shift_imm = src2w & 0x1f;
+ return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w);
+ }
+ else {
+ compiler->shift_imm = 0x20;
+ return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
+ }
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ return reg << 1;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ return push_inst(compiler, *(sljit_uw*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+
+/* 0 - no fpu
+ 1 - vfp */
+static sljit_s32 arm_fpu_type = -1;
+
+static void init_compiler(void)
+{
+ if (arm_fpu_type != -1)
+ return;
+
+ /* TODO: Only the OS can help to determine the correct fpu type. */
+ arm_fpu_type = 1;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+#ifdef SLJIT_IS_FPU_AVAILABLE
+ return SLJIT_IS_FPU_AVAILABLE;
+#else
+ if (arm_fpu_type == -1)
+ init_compiler();
+ return arm_fpu_type;
+#endif
+}
+
+#else
+
+#define arm_fpu_type 1
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+ /* Always available. */
+ return 1;
+}
+
+#endif
+
+#define FPU_LOAD (1 << 20)
+#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \
+ ((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs))
+#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \
+ ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16))
+
+static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ sljit_sw tmp;
+ sljit_uw imm;
+ sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD));
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))));
+ arg = SLJIT_MEM | TMP_REG1;
+ argw = 0;
+ }
+
+ /* Fast loads and stores. */
+ if ((arg & REG_MASK)) {
+ if (!(argw & ~0x3fc))
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & REG_MASK, reg, argw >> 2));
+ if (!(-argw & ~0x3fc))
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2));
+ }
+
+ if (compiler->cache_arg == arg) {
+ tmp = argw - compiler->cache_argw;
+ if (!(tmp & ~0x3fc))
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2));
+ if (!(-tmp & ~0x3fc))
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, reg, -tmp >> 2));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0));
+ }
+ }
+
+ if (arg & REG_MASK) {
+ if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0));
+ }
+ imm = get_imm(argw & ~0x3fc);
+ if (imm) {
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, imm)));
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2));
+ }
+ imm = get_imm(-argw & ~0x3fc);
+ if (imm) {
+ argw = -argw;
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & REG_MASK, imm)));
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2));
+ }
+ }
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ if (arg & REG_MASK) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & REG_MASK, reg_map[TMP_REG1])));
+ }
+ else
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0));
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
+ src = TMP_FREG1;
+ }
+
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_F32_OP, TMP_FREG1, src, 0)));
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, VMOV | (1 << 20) | RD(dst) | (TMP_FREG1 << 16));
+
+ /* Store the integer value from a VFP register. */
+ return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, VMOV | RD(src) | (TMP_FREG1 << 16)));
+ else if (src & SLJIT_MEM) {
+ /* Load the integer value into a VFP register. */
+ FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+ FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (TMP_FREG1 << 16)));
+ }
+
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_F32_OP, dst_r, TMP_FREG1, 0)));
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_F32_OP, src1, src2, 0)));
+ return push_inst(compiler, VMRS);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
+ op ^= SLJIT_F32_OP;
+
+ SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error);
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw));
+ src = dst_r;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_F64:
+ if (src != dst_r) {
+ if (dst_r != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_F32_OP, dst_r, src, 0)));
+ else
+ dst_r = src;
+ }
+ break;
+ case SLJIT_NEG_F64:
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_F32_OP, dst_r, src, 0)));
+ break;
+ case SLJIT_ABS_F64:
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_F32_OP, dst_r, src, 0)));
+ break;
+ case SLJIT_CONV_F64_FROM_F32:
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_F32_OP, dst_r, src, 0)));
+ op ^= SLJIT_F32_OP;
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ op ^= SLJIT_F32_OP;
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD_F64:
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));
+ break;
+
+ case SLJIT_SUB_F64:
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));
+ break;
+
+ case SLJIT_MUL_F64:
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));
+ break;
+
+ case SLJIT_DIV_F64:
+ FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));
+ break;
+ }
+
+ if (dst_r == TMP_FREG1)
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+#undef FPU_LOAD
+#undef EMIT_FPU_DATA_TRANSFER
+#undef EMIT_FPU_OPERATION
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3)));
+
+ /* Memory. */
+ if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw))
+ return compiler->error;
+ /* TMP_REG3 is used for caching. */
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))));
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw))
+ FAIL_IF(compiler->error);
+ else {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0));
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2))));
+ }
+ }
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
+ return push_inst(compiler, BLX | RM(TMP_REG3));
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+static sljit_uw get_cc(sljit_s32 type)
+{
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ case SLJIT_EQUAL_F64:
+ return 0x00000000;
+
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_NOT_EQUAL_F64:
+ return 0x10000000;
+
+ case SLJIT_LESS:
+ case SLJIT_LESS_F64:
+ return 0x30000000;
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ return 0x20000000;
+
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_F64:
+ return 0x80000000;
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return 0x90000000;
+
+ case SLJIT_SIG_LESS:
+ return 0xb0000000;
+
+ case SLJIT_SIG_GREATER_EQUAL:
+ return 0xa0000000;
+
+ case SLJIT_SIG_GREATER:
+ return 0xc0000000;
+
+ case SLJIT_SIG_LESS_EQUAL:
+ return 0xd0000000;
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_UNORDERED_F64:
+ return 0x60000000;
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_ORDERED_F64:
+ return 0x70000000;
+
+ default:
+ SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+ return 0xe0000000;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In ARM, we don't need to touch the arguments. */
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (type >= SLJIT_FAST_CALL)
+ PTR_FAIL_IF(prepare_blx(compiler));
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0,
+ type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0));
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+ jump->addr = compiler->size;
+ compiler->patches++;
+ }
+
+ if (type >= SLJIT_FAST_CALL) {
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(emit_blx(compiler));
+ }
+
+ if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
+ jump->addr = compiler->size;
+#else
+ if (type >= SLJIT_FAST_CALL)
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
+ PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type)));
+ jump->addr = compiler->size;
+#endif
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ /* In ARM, we don't need to touch the arguments. */
+ if (!(src & SLJIT_IMM)) {
+ if (FAST_IS_REG(src))
+ return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src));
+
+ SLJIT_ASSERT(src & SLJIT_MEM);
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
+ return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2));
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
+ jump->u.target = srcw;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (type >= SLJIT_FAST_CALL)
+ FAIL_IF(prepare_blx(compiler));
+ FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0));
+ if (type >= SLJIT_FAST_CALL)
+ FAIL_IF(emit_blx(compiler));
+#else
+ FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
+ FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));
+#endif
+ jump->addr = compiler->size;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ sljit_s32 dst_r, flags = GET_ALL_FLAGS(op);
+ sljit_uw cc, ins;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ op = GET_OPCODE(op);
+ cc = get_cc(type & 0xff);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ if (op < SLJIT_ADD) {
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0)));
+ FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc));
+ return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
+ }
+
+ ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP));
+ if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) {
+ FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc));
+ /* The condition must always be set, even if the ORR/EOR is not executed above. */
+ return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS;
+ }
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
+ src = TMP_REG1;
+ srcw = 0;
+ } else if (src & SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc));
+ FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)));
+ if (dst_r == TMP_REG2)
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0));
+
+ return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_const *const_;
+ sljit_s32 reg;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+
+ reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value));
+ compiler->patches++;
+#else
+ PTR_FAIL_IF(emit_imm(compiler, reg, init_value));
+#endif
+ set_const(const_, compiler);
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ inline_set_jump_addr(addr, executable_offset, new_target, 1);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ inline_set_const(addr, executable_offset, new_constant, 1);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
new file mode 100644
index 0000000000..2062d80b0a
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
@@ -0,0 +1,2062 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "ARM-64" SLJIT_CPUINFO;
+}
+
+/* Length of an instruction word */
+typedef sljit_u32 sljit_ins;
+
+#define TMP_ZERO (0)
+
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+#define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 5)
+#define TMP_SP (SLJIT_NUMBER_OF_REGISTERS + 6)
+
+#define TMP_FREG1 (0)
+#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
+ 31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31
+};
+
+#define W_OP (1 << 31)
+#define RD(rd) (reg_map[rd])
+#define RT(rt) (reg_map[rt])
+#define RN(rn) (reg_map[rn] << 5)
+#define RT2(rt2) (reg_map[rt2] << 10)
+#define RM(rm) (reg_map[rm] << 16)
+#define VD(vd) (vd)
+#define VT(vt) (vt)
+#define VN(vn) ((vn) << 5)
+#define VM(vm) ((vm) << 16)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+#define ADC 0x9a000000
+#define ADD 0x8b000000
+#define ADDI 0x91000000
+#define AND 0x8a000000
+#define ANDI 0x92000000
+#define ASRV 0x9ac02800
+#define B 0x14000000
+#define B_CC 0x54000000
+#define BL 0x94000000
+#define BLR 0xd63f0000
+#define BR 0xd61f0000
+#define BRK 0xd4200000
+#define CBZ 0xb4000000
+#define CLZ 0xdac01000
+#define CSINC 0x9a800400
+#define EOR 0xca000000
+#define EORI 0xd2000000
+#define FABS 0x1e60c000
+#define FADD 0x1e602800
+#define FCMP 0x1e602000
+#define FCVT 0x1e224000
+#define FCVTZS 0x9e780000
+#define FDIV 0x1e601800
+#define FMOV 0x1e604000
+#define FMUL 0x1e600800
+#define FNEG 0x1e614000
+#define FSUB 0x1e603800
+#define LDRI 0xf9400000
+#define LDP 0xa9400000
+#define LDP_PST 0xa8c00000
+#define LSLV 0x9ac02000
+#define LSRV 0x9ac02400
+#define MADD 0x9b000000
+#define MOVK 0xf2800000
+#define MOVN 0x92800000
+#define MOVZ 0xd2800000
+#define NOP 0xd503201f
+#define ORN 0xaa200000
+#define ORR 0xaa000000
+#define ORRI 0xb2000000
+#define RET 0xd65f0000
+#define SBC 0xda000000
+#define SBFM 0x93000000
+#define SCVTF 0x9e620000
+#define SDIV 0x9ac00c00
+#define SMADDL 0x9b200000
+#define SMULH 0x9b403c00
+#define STP 0xa9000000
+#define STP_PRE 0xa9800000
+#define STRI 0xf9000000
+#define STR_FI 0x3d000000
+#define STR_FR 0x3c206800
+#define STUR_FI 0x3c000000
+#define SUB 0xcb000000
+#define SUBI 0xd1000000
+#define SUBS 0xeb000000
+#define UBFM 0xd3000000
+#define UDIV 0x9ac00800
+#define UMULH 0x9bc03c00
+
+/* dest_reg is the absolute name of the register
+ Useful for reordering instructions in the delay slot. */
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
+{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
+{
+ FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
+ FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21)));
+ FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21)));
+ return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21));
+}
+
+static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
+{
+ sljit_s32 dst = inst[0] & 0x1f;
+ SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
+ inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5);
+ inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21);
+ inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21);
+ inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
+}
+
+static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+{
+ sljit_sw diff;
+ sljit_uw target_addr;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+ jump->flags |= PATCH_ABS64;
+ return 0;
+ }
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
+ }
+
+ diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset;
+
+ if (jump->flags & IS_COND) {
+ diff += sizeof(sljit_ins);
+ if (diff <= 0xfffff && diff >= -0x100000) {
+ code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;
+ jump->addr -= sizeof(sljit_ins);
+ jump->flags |= PATCH_COND;
+ return 5;
+ }
+ diff -= sizeof(sljit_ins);
+ }
+
+ if (diff <= 0x7ffffff && diff >= -0x8000000) {
+ jump->flags |= PATCH_B;
+ return 4;
+ }
+
+ if (target_addr <= 0xffffffffl) {
+ if (jump->flags & IS_COND)
+ code_ptr[-5] -= (2 << 5);
+ code_ptr[-2] = code_ptr[0];
+ return 2;
+ }
+ if (target_addr <= 0xffffffffffffl) {
+ if (jump->flags & IS_COND)
+ code_ptr[-5] -= (1 << 5);
+ jump->flags |= PATCH_ABS48;
+ code_ptr[-1] = code_ptr[0];
+ return 1;
+ }
+
+ jump->flags |= PATCH_ABS64;
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_sw executable_offset;
+ sljit_uw addr;
+ sljit_s32 dst;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ /* These structures are ordered by their address. */
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+ jump->addr = (sljit_uw)(code_ptr - 4);
+ code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins *)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
+ SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000);
+ buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff);
+ if (jump->flags & IS_COND)
+ buf_ptr[-1] -= (4 << 5);
+ break;
+ }
+ if (jump->flags & PATCH_COND) {
+ addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
+ SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000);
+ buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
+ break;
+ }
+
+ SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl);
+ SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl);
+
+ dst = buf_ptr[0] & 0x1f;
+ buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5);
+ buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21);
+ if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))
+ buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21);
+ if (jump->flags & PATCH_ABS64)
+ buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21);
+ } while (0);
+ jump = jump->next;
+ }
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+
+ code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ return code;
+}
+
+/* --------------------------------------------------------------------- */
+/* Core code generator functions. */
+/* --------------------------------------------------------------------- */
+
+#define COUNT_TRAILING_ZERO(value, result) \
+ result = 0; \
+ if (!(value & 0xffffffff)) { \
+ result += 32; \
+ value >>= 32; \
+ } \
+ if (!(value & 0xffff)) { \
+ result += 16; \
+ value >>= 16; \
+ } \
+ if (!(value & 0xff)) { \
+ result += 8; \
+ value >>= 8; \
+ } \
+ if (!(value & 0xf)) { \
+ result += 4; \
+ value >>= 4; \
+ } \
+ if (!(value & 0x3)) { \
+ result += 2; \
+ value >>= 2; \
+ } \
+ if (!(value & 0x1)) { \
+ result += 1; \
+ value >>= 1; \
+ }
+
+#define LOGICAL_IMM_CHECK 0x100
+
+static sljit_ins logical_imm(sljit_sw imm, sljit_s32 len)
+{
+ sljit_s32 negated, ones, right;
+ sljit_uw mask, uimm;
+ sljit_ins ins;
+
+ if (len & LOGICAL_IMM_CHECK) {
+ len &= ~LOGICAL_IMM_CHECK;
+ if (len == 32 && (imm == 0 || imm == -1))
+ return 0;
+ if (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1))
+ return 0;
+ }
+
+ SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1)
+ || (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1));
+ uimm = (sljit_uw)imm;
+ while (1) {
+ if (len <= 0) {
+ SLJIT_ASSERT_STOP();
+ return 0;
+ }
+ mask = ((sljit_uw)1 << len) - 1;
+ if ((uimm & mask) != ((uimm >> len) & mask))
+ break;
+ len >>= 1;
+ }
+
+ len <<= 1;
+
+ negated = 0;
+ if (uimm & 0x1) {
+ negated = 1;
+ uimm = ~uimm;
+ }
+
+ if (len < 64)
+ uimm &= ((sljit_uw)1 << len) - 1;
+
+ /* Unsigned right shift. */
+ COUNT_TRAILING_ZERO(uimm, right);
+
+ /* Signed shift. We also know that the highest bit is set. */
+ imm = (sljit_sw)~uimm;
+ SLJIT_ASSERT(imm < 0);
+
+ COUNT_TRAILING_ZERO(imm, ones);
+
+ if (~imm)
+ return 0;
+
+ if (len == 64)
+ ins = 1 << 22;
+ else
+ ins = (0x3f - ((len << 1) - 1)) << 10;
+
+ if (negated)
+ return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16);
+
+ return ins | ((ones - 1) << 10) | ((len - right) << 16);
+}
+
+#undef COUNT_TRAILING_ZERO
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm)
+{
+ sljit_uw imm = (sljit_uw)simm;
+ sljit_s32 i, zeros, ones, first;
+ sljit_ins bitmask;
+
+ if (imm <= 0xffff)
+ return push_inst(compiler, MOVZ | RD(dst) | (imm << 5));
+
+ if (simm >= -0x10000 && simm < 0)
+ return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5));
+
+ if (imm <= 0xffffffffl) {
+ if ((imm & 0xffff0000l) == 0xffff0000)
+ return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5));
+ if ((imm & 0xffff) == 0xffff)
+ return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
+ bitmask = logical_imm(simm, 16);
+ if (bitmask != 0)
+ return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask);
+ }
+ else {
+ bitmask = logical_imm(simm, 32);
+ if (bitmask != 0)
+ return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask);
+ }
+
+ if (imm <= 0xffffffffl) {
+ FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
+ return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
+ }
+
+ if (simm >= -0x100000000l && simm < 0) {
+ FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)));
+ return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
+ }
+
+ /* A large amount of number can be constructed from ORR and MOVx,
+ but computing them is costly. We don't */
+
+ zeros = 0;
+ ones = 0;
+ for (i = 4; i > 0; i--) {
+ if ((simm & 0xffff) == 0)
+ zeros++;
+ if ((simm & 0xffff) == 0xffff)
+ ones++;
+ simm >>= 16;
+ }
+
+ simm = (sljit_sw)imm;
+ first = 1;
+ if (ones > zeros) {
+ simm = ~simm;
+ for (i = 0; i < 4; i++) {
+ if (!(simm & 0xffff)) {
+ simm >>= 16;
+ continue;
+ }
+ if (first) {
+ first = 0;
+ FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
+ }
+ else
+ FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21)));
+ simm >>= 16;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (!(simm & 0xffff)) {
+ simm >>= 16;
+ continue;
+ }
+ if (first) {
+ first = 0;
+ FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
+ }
+ else
+ FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
+ simm >>= 16;
+ }
+ return SLJIT_SUCCESS;
+}
+
+#define ARG1_IMM 0x0010000
+#define ARG2_IMM 0x0020000
+#define INT_OP 0x0040000
+#define SET_FLAGS 0x0080000
+#define UNUSED_RETURN 0x0100000
+#define SLOW_DEST 0x0200000
+#define SLOW_SRC1 0x0400000
+#define SLOW_SRC2 0x0800000
+
+#define CHECK_FLAGS(flag_bits) \
+ if (flags & SET_FLAGS) { \
+ inv_bits |= flag_bits; \
+ if (flags & UNUSED_RETURN) \
+ dst = TMP_ZERO; \
+ }
+
+static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2)
+{
+ /* dst must be register, TMP_REG1
+ arg1 must be register, TMP_REG1, imm
+ arg2 must be register, TMP_REG2, imm */
+ sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0;
+ sljit_ins inst_bits;
+ sljit_s32 op = (flags & 0xffff);
+ sljit_s32 reg;
+ sljit_sw imm, nimm;
+
+ if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
+ /* Both are immediates. */
+ flags &= ~ARG1_IMM;
+ if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB)
+ arg1 = TMP_ZERO;
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+ }
+
+ if (flags & (ARG1_IMM | ARG2_IMM)) {
+ reg = (flags & ARG2_IMM) ? arg1 : arg2;
+ imm = (flags & ARG2_IMM) ? arg2 : arg1;
+
+ switch (op) {
+ case SLJIT_MUL:
+ case SLJIT_NEG:
+ case SLJIT_CLZ:
+ case SLJIT_ADDC:
+ case SLJIT_SUBC:
+ /* No form with immediate operand (except imm 0, which
+ is represented by a ZERO register). */
+ break;
+ case SLJIT_MOV:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
+ return load_immediate(compiler, dst, imm);
+ case SLJIT_NOT:
+ SLJIT_ASSERT(flags & ARG2_IMM);
+ FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm));
+ goto set_flags;
+ case SLJIT_SUB:
+ if (flags & ARG1_IMM)
+ break;
+ imm = -imm;
+ /* Fall through. */
+ case SLJIT_ADD:
+ if (imm == 0) {
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg));
+ }
+ if (imm > 0 && imm <= 0xfff) {
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10));
+ }
+ nimm = -imm;
+ if (nimm > 0 && nimm <= 0xfff) {
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10));
+ }
+ if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) {
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22));
+ }
+ if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) {
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22));
+ }
+ if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) {
+ FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)));
+ return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10));
+ }
+ if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) {
+ FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)));
+ return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10));
+ }
+ break;
+ case SLJIT_AND:
+ inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
+ if (!inst_bits)
+ break;
+ CHECK_FLAGS(3 << 29);
+ return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits);
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
+ if (!inst_bits)
+ break;
+ if (op == SLJIT_OR)
+ inst_bits |= ORRI;
+ else
+ inst_bits |= EORI;
+ FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg)));
+ goto set_flags;
+ case SLJIT_SHL:
+ if (flags & ARG1_IMM)
+ break;
+ if (flags & INT_OP) {
+ imm &= 0x1f;
+ FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10)));
+ }
+ else {
+ imm &= 0x3f;
+ FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10)));
+ }
+ goto set_flags;
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+ if (flags & ARG1_IMM)
+ break;
+ if (op == SLJIT_ASHR)
+ inv_bits |= 1 << 30;
+ if (flags & INT_OP) {
+ imm &= 0x1f;
+ FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10)));
+ }
+ else {
+ imm &= 0x3f;
+ FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10)));
+ }
+ goto set_flags;
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ if (flags & ARG2_IMM) {
+ if (arg2 == 0)
+ arg2 = TMP_ZERO;
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
+ arg2 = TMP_REG2;
+ }
+ }
+ else {
+ if (arg1 == 0)
+ arg1 = TMP_ZERO;
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+ }
+ }
+
+ /* Both arguments are registers. */
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_P:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (dst == arg2)
+ return SLJIT_SUCCESS;
+ return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2));
+ case SLJIT_MOV_U8:
+ case SLJIT_MOVU_U8:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10));
+ case SLJIT_MOV_S8:
+ case SLJIT_MOVU_S8:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (!(flags & INT_OP))
+ inv_bits |= 1 << 22;
+ return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));
+ case SLJIT_MOV_U16:
+ case SLJIT_MOVU_U16:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10));
+ case SLJIT_MOV_S16:
+ case SLJIT_MOVU_S16:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (!(flags & INT_OP))
+ inv_bits |= 1 << 22;
+ return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));
+ case SLJIT_MOV_U32:
+ case SLJIT_MOVU_U32:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if ((flags & INT_OP) && dst == arg2)
+ return SLJIT_SUCCESS;
+ return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
+ case SLJIT_MOV_S32:
+ case SLJIT_MOVU_S32:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if ((flags & INT_OP) && dst == arg2)
+ return SLJIT_SUCCESS;
+ return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10));
+ case SLJIT_NOT:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)));
+ goto set_flags;
+ case SLJIT_NEG:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ if (flags & SET_FLAGS)
+ inv_bits |= 1 << 29;
+ return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2)));
+ goto set_flags;
+ case SLJIT_ADD:
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
+ case SLJIT_ADDC:
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
+ case SLJIT_SUB:
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
+ case SLJIT_SUBC:
+ CHECK_FLAGS(1 << 29);
+ return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
+ case SLJIT_MUL:
+ if (!(flags & SET_FLAGS))
+ return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO));
+ if (flags & INT_OP) {
+ FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10)));
+ FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));
+ return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
+ }
+ FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2)));
+ FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)));
+ return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
+ case SLJIT_AND:
+ CHECK_FLAGS(3 << 29);
+ return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
+ case SLJIT_OR:
+ FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
+ goto set_flags;
+ case SLJIT_XOR:
+ FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
+ goto set_flags;
+ case SLJIT_SHL:
+ FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
+ goto set_flags;
+ case SLJIT_LSHR:
+ FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
+ goto set_flags;
+ case SLJIT_ASHR:
+ FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
+ goto set_flags;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+set_flags:
+ if (flags & SET_FLAGS)
+ return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO));
+ return SLJIT_SUCCESS;
+}
+
+#define STORE 0x01
+#define SIGNED 0x02
+
+#define UPDATE 0x04
+#define ARG_TEST 0x08
+
+#define BYTE_SIZE 0x000
+#define HALF_SIZE 0x100
+#define INT_SIZE 0x200
+#define WORD_SIZE 0x300
+
+#define MEM_SIZE_SHIFT(flags) ((flags) >> 8)
+
+static const sljit_ins sljit_mem_imm[4] = {
+/* u l */ 0x39400000 /* ldrb [reg,imm] */,
+/* u s */ 0x39000000 /* strb [reg,imm] */,
+/* s l */ 0x39800000 /* ldrsb [reg,imm] */,
+/* s s */ 0x39000000 /* strb [reg,imm] */,
+};
+
+static const sljit_ins sljit_mem_simm[4] = {
+/* u l */ 0x38400000 /* ldurb [reg,imm] */,
+/* u s */ 0x38000000 /* sturb [reg,imm] */,
+/* s l */ 0x38800000 /* ldursb [reg,imm] */,
+/* s s */ 0x38000000 /* sturb [reg,imm] */,
+};
+
+static const sljit_ins sljit_mem_pre_simm[4] = {
+/* u l */ 0x38400c00 /* ldrb [reg,imm]! */,
+/* u s */ 0x38000c00 /* strb [reg,imm]! */,
+/* s l */ 0x38800c00 /* ldrsb [reg,imm]! */,
+/* s s */ 0x38000c00 /* strb [reg,imm]! */,
+};
+
+static const sljit_ins sljit_mem_reg[4] = {
+/* u l */ 0x38606800 /* ldrb [reg,reg] */,
+/* u s */ 0x38206800 /* strb [reg,reg] */,
+/* s l */ 0x38a06800 /* ldrsb [reg,reg] */,
+/* s s */ 0x38206800 /* strb [reg,reg] */,
+};
+
+/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
+static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
+{
+ if (value >= 0) {
+ if (value <= 0xfff)
+ return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10));
+ if (value <= 0xffffff && !(value & 0xfff))
+ return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
+ }
+ else {
+ value = -value;
+ if (value <= 0xfff)
+ return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10));
+ if (value <= 0xffffff && !(value & 0xfff))
+ return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+/* Can perform an operation using at most 1 instruction. */
+static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ sljit_u32 shift = MEM_SIZE_SHIFT(flags);
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (SLJIT_UNLIKELY(flags & UPDATE)) {
+ if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) {
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ arg &= REG_MASK;
+ argw &= 0x1ff;
+ FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3]
+ | (shift << 30) | RT(reg) | RN(arg) | (argw << 12)));
+ return -1;
+ }
+ return 0;
+ }
+
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ argw &= 0x3;
+ if (argw && argw != shift)
+ return 0;
+
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg)
+ | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)));
+ return -1;
+ }
+
+ arg &= REG_MASK;
+ if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) {
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
+ | RT(reg) | RN(arg) | (argw << (10 - shift))));
+ return -1;
+ }
+
+ if (argw > 255 || argw < -256)
+ return 0;
+
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
+ | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12)));
+ return -1;
+}
+
+/* see getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_sw diff;
+ if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
+ return 0;
+
+ if (!(arg & REG_MASK)) {
+ diff = argw - next_argw;
+ if (diff <= 0xfff && diff >= -0xfff)
+ return 1;
+ return 0;
+ }
+
+ if (argw == next_argw)
+ return 1;
+
+ diff = argw - next_argw;
+ if (arg == next_arg && diff <= 0xfff && diff >= -0xfff)
+ return 1;
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
+ sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_u32 shift = MEM_SIZE_SHIFT(flags);
+ sljit_s32 tmp_r, other_r;
+ sljit_sw diff;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ tmp_r = (flags & STORE) ? TMP_REG3 : reg;
+
+ if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) {
+ /* Update only applies if a base register exists. */
+ other_r = OFFS_REG(arg);
+ if (!other_r) {
+ other_r = arg & REG_MASK;
+ if (other_r != reg && argw >= 0 && argw <= 0xffffff) {
+ if ((argw & 0xfff) != 0)
+ FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
+ if (argw >> 12)
+ FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
+ return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
+ }
+ else if (other_r != reg && argw < 0 && argw >= -0xffffff) {
+ argw = -argw;
+ if ((argw & 0xfff) != 0)
+ FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
+ if (argw >> 12)
+ FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
+ return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM) {
+ if (argw == compiler->cache_argw) {
+ other_r = TMP_REG3;
+ argw = 0;
+ }
+ else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ other_r = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ if (argw) {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ other_r = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ /* No caching here. */
+ arg &= REG_MASK;
+ argw &= 0x3;
+ if (!argw || argw == shift) {
+ FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0)));
+ return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10));
+ }
+ if (arg != reg) {
+ FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)));
+ return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
+ }
+ FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10)));
+ FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR)));
+ return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR));
+ }
+
+ if (arg & OFFS_REG_MASK) {
+ other_r = OFFS_REG(arg);
+ arg &= REG_MASK;
+ FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10)));
+ return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r));
+ }
+
+ if (compiler->cache_arg == arg) {
+ diff = argw - compiler->cache_argw;
+ if (diff <= 255 && diff >= -256)
+ return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
+ | RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
+ }
+ }
+
+ if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) {
+ FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10)));
+ return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
+ | RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift)));
+ }
+
+ diff = argw - next_argw;
+ next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0;
+ arg &= REG_MASK;
+
+ if (arg && compiler->cache_arg == SLJIT_MEM) {
+ if (compiler->cache_argw == argw)
+ return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
+ }
+ }
+
+ compiler->cache_argw = argw;
+ if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+
+ if (next_arg) {
+ FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg)));
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ }
+
+ if (arg)
+ return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
+ return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3));
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ return compiler->error;
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 i, tmp, offs, prev, saved_regs_size;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0);
+ local_size += saved_regs_size + SLJIT_LOCALS_OFFSET;
+ local_size = (local_size + 15) & ~0xf;
+ compiler->local_size = local_size;
+
+ if (local_size <= (63 * sizeof(sljit_sw))) {
+ FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
+ | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15)));
+ FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
+ offs = (local_size - saved_regs_size) << (15 - 3);
+ } else {
+ offs = 0 << 15;
+ if (saved_regs_size & 0x8) {
+ offs = 1 << 15;
+ saved_regs_size += sizeof(sljit_sw);
+ }
+ local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
+ if (saved_regs_size > 0)
+ FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
+ }
+
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ prev = -1;
+ for (i = SLJIT_S0; i >= tmp; i--) {
+ if (prev == -1) {
+ if (!(offs & (1 << 15))) {
+ prev = i;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
+ offs += 1 << 15;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
+ offs += 2 << 15;
+ prev = -1;
+ }
+
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
+ if (prev == -1) {
+ if (!(offs & (1 << 15))) {
+ prev = i;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
+ offs += 1 << 15;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
+ offs += 2 << 15;
+ prev = -1;
+ }
+
+ SLJIT_ASSERT(prev == -1);
+
+ if (compiler->local_size > (63 * sizeof(sljit_sw))) {
+ /* The local_size is already adjusted by the saved registers. */
+ if (local_size > 0xfff) {
+ FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
+ local_size &= 0xfff;
+ }
+ if (local_size)
+ FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
+ FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
+ | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15)));
+ FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
+ }
+
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0)));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1)));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET;
+ local_size = (local_size + 15) & ~0xf;
+ compiler->local_size = local_size;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 local_size;
+ sljit_s32 i, tmp, offs, prev, saved_regs_size;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ local_size = compiler->local_size;
+
+ saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0);
+ if (local_size <= (63 * sizeof(sljit_sw)))
+ offs = (local_size - saved_regs_size) << (15 - 3);
+ else {
+ FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
+ | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15)));
+ offs = 0 << 15;
+ if (saved_regs_size & 0x8) {
+ offs = 1 << 15;
+ saved_regs_size += sizeof(sljit_sw);
+ }
+ local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
+ if (local_size > 0xfff) {
+ FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
+ local_size &= 0xfff;
+ }
+ if (local_size)
+ FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
+ }
+
+ tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
+ prev = -1;
+ for (i = SLJIT_S0; i >= tmp; i--) {
+ if (prev == -1) {
+ if (!(offs & (1 << 15))) {
+ prev = i;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
+ offs += 1 << 15;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
+ offs += 2 << 15;
+ prev = -1;
+ }
+
+ for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
+ if (prev == -1) {
+ if (!(offs & (1 << 15))) {
+ prev = i;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
+ offs += 1 << 15;
+ continue;
+ }
+ FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
+ offs += 2 << 15;
+ prev = -1;
+ }
+
+ SLJIT_ASSERT(prev == -1);
+
+ if (compiler->local_size <= (63 * sizeof(sljit_sw))) {
+ FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
+ | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
+ } else if (saved_regs_size > 0) {
+ FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
+ }
+
+ FAIL_IF(push_inst(compiler, RET | RN(TMP_LR)));
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ sljit_ins inv_bits = (op & SLJIT_I32_OP) ? (1 << 31) : 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ return push_inst(compiler, BRK);
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP);
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+ FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
+ FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
+ return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
+ FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
+ FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
+ return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+ return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r, flags, mem_flags;
+ sljit_s32 op_flags = GET_ALL_FLAGS(op);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+
+ op = GET_OPCODE(op);
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ flags = WORD_SIZE;
+ break;
+ case SLJIT_MOV_U8:
+ flags = BYTE_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u8)srcw;
+ break;
+ case SLJIT_MOV_S8:
+ flags = BYTE_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s8)srcw;
+ break;
+ case SLJIT_MOV_U16:
+ flags = HALF_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u16)srcw;
+ break;
+ case SLJIT_MOV_S16:
+ flags = HALF_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s16)srcw;
+ break;
+ case SLJIT_MOV_U32:
+ flags = INT_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u32)srcw;
+ break;
+ case SLJIT_MOV_S32:
+ flags = INT_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s32)srcw;
+ break;
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_P:
+ flags = WORD_SIZE | UPDATE;
+ break;
+ case SLJIT_MOVU_U8:
+ flags = BYTE_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u8)srcw;
+ break;
+ case SLJIT_MOVU_S8:
+ flags = BYTE_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s8)srcw;
+ break;
+ case SLJIT_MOVU_U16:
+ flags = HALF_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u16)srcw;
+ break;
+ case SLJIT_MOVU_S16:
+ flags = HALF_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s16)srcw;
+ break;
+ case SLJIT_MOVU_U32:
+ flags = INT_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u32)srcw;
+ break;
+ case SLJIT_MOVU_S32:
+ flags = INT_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s32)srcw;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ flags = 0;
+ break;
+ }
+
+ if (src & SLJIT_IMM)
+ FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
+ } else {
+ if (dst_r != TMP_REG1)
+ return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
+ dst_r = src;
+ }
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0;
+ mem_flags = WORD_SIZE;
+ if (op_flags & SLJIT_I32_OP) {
+ flags |= INT_OP;
+ mem_flags = INT_SIZE;
+ }
+
+ if (dst == SLJIT_UNUSED)
+ flags |= UNUSED_RETURN;
+
+ if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw));
+ src = TMP_REG2;
+ }
+
+ if (src & SLJIT_IMM) {
+ flags |= ARG2_IMM;
+ if (op_flags & SLJIT_I32_OP)
+ srcw = (sljit_s32)srcw;
+ } else
+ srcw = src;
+
+ emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw);
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r, flags, mem_flags;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+ flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+ mem_flags = WORD_SIZE;
+ if (op & SLJIT_I32_OP) {
+ flags |= INT_OP;
+ mem_flags = INT_SIZE;
+ }
+
+ if (dst == SLJIT_UNUSED)
+ flags |= UNUSED_RETURN;
+
+ if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ }
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
+
+ if (src1 & SLJIT_MEM)
+ src1 = TMP_REG1;
+ if (src2 & SLJIT_MEM)
+ src2 = TMP_REG2;
+
+ if (src1 & SLJIT_IMM)
+ flags |= ARG1_IMM;
+ else
+ src1w = src1;
+ if (src2 & SLJIT_IMM)
+ flags |= ARG2_IMM;
+ else
+ src2w = src2;
+
+ emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ return reg;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ return push_inst(compiler, *(sljit_ins*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+#ifdef SLJIT_IS_FPU_AVAILABLE
+ return SLJIT_IS_FPU_AVAILABLE;
+#else
+ /* Available by default. */
+ return 1;
+#endif
+}
+
+static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ sljit_u32 shift = MEM_SIZE_SHIFT(flags);
+ sljit_ins ins_bits = (shift << 30);
+ sljit_s32 other_r;
+ sljit_sw diff;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (!(flags & STORE))
+ ins_bits |= 1 << 22;
+
+ if (arg & OFFS_REG_MASK) {
+ argw &= 3;
+ if (!argw || argw == shift)
+ return push_inst(compiler, STR_FR | ins_bits | VT(reg)
+ | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
+ other_r = OFFS_REG(arg);
+ arg &= REG_MASK;
+ FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10)));
+ arg = TMP_REG1;
+ argw = 0;
+ }
+
+ arg &= REG_MASK;
+ if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0)
+ return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift)));
+
+ if (arg && argw <= 255 && argw >= -256)
+ return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12));
+
+ /* Slow cases */
+ if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) {
+ diff = argw - compiler->cache_argw;
+ if (!arg && diff <= 255 && diff >= -256)
+ return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ }
+ }
+
+ if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) {
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ }
+
+ if (arg & REG_MASK)
+ return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3));
+ return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3));
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+ sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
+
+ if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64)
+ inv_bits |= (1 << 31);
+
+ if (src & SLJIT_MEM) {
+ emit_fop_mem(compiler, (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);
+ src = TMP_FREG1;
+ }
+
+ FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));
+
+ if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
+ return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+ sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
+
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
+ inv_bits |= (1 << 31);
+
+ if (src & SLJIT_MEM) {
+ emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw);
+ src = TMP_REG1;
+ } else if (src & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
+ srcw = (sljit_s32)srcw;
+#endif
+ FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+ src = TMP_REG1;
+ }
+
+ FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src)));
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, ((op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;
+ sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
+
+ if (src1 & SLJIT_MEM) {
+ emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
+ src1 = TMP_FREG1;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
+ src2 = TMP_FREG2;
+ }
+
+ return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;
+ sljit_ins inv_bits;
+
+ CHECK_ERROR();
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference);
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
+
+ inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (src & SLJIT_MEM) {
+ emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw);
+ src = dst_r;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_F64:
+ if (src != dst_r) {
+ if (dst_r != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
+ else
+ dst_r = src;
+ }
+ break;
+ case SLJIT_NEG_F64:
+ FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));
+ break;
+ case SLJIT_ABS_F64:
+ FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));
+ break;
+ case SLJIT_CONV_F64_FROM_F32:
+ FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_F32_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;
+ sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+ if (src1 & SLJIT_MEM) {
+ emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
+ src1 = TMP_FREG1;
+ }
+ if (src2 & SLJIT_MEM) {
+ emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
+ src2 = TMP_FREG2;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD_F64:
+ FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
+ break;
+ case SLJIT_SUB_F64:
+ FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
+ break;
+ case SLJIT_MUL_F64:
+ FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
+ break;
+ case SLJIT_DIV_F64:
+ FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
+ break;
+ }
+
+ if (!(dst & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw);
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR));
+
+ /* Memory. */
+ return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_LR, srcw));
+
+ return push_inst(compiler, RET | RN(TMP_LR));
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+static sljit_uw get_cc(sljit_s32 type)
+{
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ case SLJIT_EQUAL_F64:
+ return 0x1;
+
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_NOT_EQUAL_F64:
+ return 0x0;
+
+ case SLJIT_LESS:
+ case SLJIT_LESS_F64:
+ return 0x2;
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ return 0x3;
+
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_F64:
+ return 0x9;
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return 0x8;
+
+ case SLJIT_SIG_LESS:
+ return 0xa;
+
+ case SLJIT_SIG_GREATER_EQUAL:
+ return 0xb;
+
+ case SLJIT_SIG_GREATER:
+ return 0xd;
+
+ case SLJIT_SIG_LESS_EQUAL:
+ return 0xc;
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_UNORDERED_F64:
+ return 0x7;
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_ORDERED_F64:
+ return 0x6;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return 0xe;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type < SLJIT_JUMP) {
+ jump->flags |= IS_COND;
+ PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type)));
+ }
+ else if (type >= SLJIT_FAST_CALL)
+ jump->flags |= IS_BL;
+
+ PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)));
+
+ return jump;
+}
+
+static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src, sljit_sw srcw)
+{
+ struct sljit_jump *jump;
+ sljit_ins inv_bits = (type & SLJIT_I32_OP) ? (1 << 31) : 0;
+
+ SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ jump->flags |= IS_CBZ | IS_COND;
+
+ if (src & SLJIT_MEM) {
+ PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw));
+ src = TMP_REG1;
+ }
+ else if (src & SLJIT_IMM) {
+ PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+ src = TMP_REG1;
+ }
+ SLJIT_ASSERT(FAST_IS_REG(src));
+
+ if ((type & 0xff) == SLJIT_EQUAL)
+ inv_bits |= 1 << 24;
+
+ PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));
+ PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1)));
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ /* In ARM, we don't need to touch the arguments. */
+ if (!(src & SLJIT_IMM)) {
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw));
+ src = TMP_REG1;
+ }
+ return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src));
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
+ jump->u.target = srcw;
+
+ FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
+ jump->addr = compiler->size;
+ return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ sljit_s32 dst_r, flags, mem_flags;
+ sljit_ins cc;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ cc = get_cc(type & 0xff);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if (GET_OPCODE(op) < SLJIT_ADD) {
+ FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));
+ if (dst_r != TMP_REG1)
+ return SLJIT_SUCCESS;
+ return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw);
+ }
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+ mem_flags = WORD_SIZE;
+ if (op & SLJIT_I32_OP) {
+ flags |= INT_OP;
+ mem_flags = INT_SIZE;
+ }
+
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw));
+ src = TMP_REG1;
+ srcw = 0;
+ } else if (src & SLJIT_IMM)
+ flags |= ARG1_IMM;
+
+ FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO)));
+ emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2);
+
+ if (dst_r != TMP_REG1)
+ return SLJIT_SUCCESS;
+ return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_const *const_;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+ PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ sljit_ins* inst = (sljit_ins*)addr;
+ modify_imm64_const(inst, new_target);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 4);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_ins* inst = (sljit_ins*)addr;
+ modify_imm64_const(inst, new_constant);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 4);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
new file mode 100644
index 0000000000..95afc5231f
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
@@ -0,0 +1,2102 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "ARM-Thumb2" SLJIT_CPUINFO;
+}
+
+/* Length of an instruction word. */
+typedef sljit_u32 sljit_ins;
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5)
+
+#define TMP_FREG1 (0)
+#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+
+/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
+ 0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15
+};
+
+#define COPY_BITS(src, from, to, bits) \
+ ((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to))
+
+/* Thumb16 encodings. */
+#define RD3(rd) (reg_map[rd])
+#define RN3(rn) (reg_map[rn] << 3)
+#define RM3(rm) (reg_map[rm] << 6)
+#define RDN3(rdn) (reg_map[rdn] << 8)
+#define IMM3(imm) (imm << 6)
+#define IMM8(imm) (imm)
+
+/* Thumb16 helpers. */
+#define SET_REGS44(rd, rn) \
+ ((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4))
+#define IS_2_LO_REGS(reg1, reg2) \
+ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7)
+#define IS_3_LO_REGS(reg1, reg2, reg3) \
+ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7)
+
+/* Thumb32 encodings. */
+#define RD4(rd) (reg_map[rd] << 8)
+#define RN4(rn) (reg_map[rn] << 16)
+#define RM4(rm) (reg_map[rm])
+#define RT4(rt) (reg_map[rt] << 12)
+#define DD4(dd) ((dd) << 12)
+#define DN4(dn) ((dn) << 16)
+#define DM4(dm) (dm)
+#define IMM5(imm) \
+ (COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6))
+#define IMM12(imm) \
+ (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+/* dot '.' changed to _
+ I immediate form (possibly followed by number of immediate bits). */
+#define ADCI 0xf1400000
+#define ADCS 0x4140
+#define ADC_W 0xeb400000
+#define ADD 0x4400
+#define ADDS 0x1800
+#define ADDSI3 0x1c00
+#define ADDSI8 0x3000
+#define ADD_W 0xeb000000
+#define ADDWI 0xf2000000
+#define ADD_SP 0xb000
+#define ADD_W 0xeb000000
+#define ADD_WI 0xf1000000
+#define ANDI 0xf0000000
+#define ANDS 0x4000
+#define AND_W 0xea000000
+#define ASRS 0x4100
+#define ASRSI 0x1000
+#define ASR_W 0xfa40f000
+#define ASR_WI 0xea4f0020
+#define BICI 0xf0200000
+#define BKPT 0xbe00
+#define BLX 0x4780
+#define BX 0x4700
+#define CLZ 0xfab0f080
+#define CMPI 0x2800
+#define CMP_W 0xebb00f00
+#define EORI 0xf0800000
+#define EORS 0x4040
+#define EOR_W 0xea800000
+#define IT 0xbf00
+#define LSLS 0x4080
+#define LSLSI 0x0000
+#define LSL_W 0xfa00f000
+#define LSL_WI 0xea4f0000
+#define LSRS 0x40c0
+#define LSRSI 0x0800
+#define LSR_W 0xfa20f000
+#define LSR_WI 0xea4f0010
+#define MOV 0x4600
+#define MOVS 0x0000
+#define MOVSI 0x2000
+#define MOVT 0xf2c00000
+#define MOVW 0xf2400000
+#define MOV_W 0xea4f0000
+#define MOV_WI 0xf04f0000
+#define MUL 0xfb00f000
+#define MVNS 0x43c0
+#define MVN_W 0xea6f0000
+#define MVN_WI 0xf06f0000
+#define NOP 0xbf00
+#define ORNI 0xf0600000
+#define ORRI 0xf0400000
+#define ORRS 0x4300
+#define ORR_W 0xea400000
+#define POP 0xbc00
+#define POP_W 0xe8bd0000
+#define PUSH 0xb400
+#define PUSH_W 0xe92d0000
+#define RSB_WI 0xf1c00000
+#define RSBSI 0x4240
+#define SBCI 0xf1600000
+#define SBCS 0x4180
+#define SBC_W 0xeb600000
+#define SMULL 0xfb800000
+#define STR_SP 0x9000
+#define SUBS 0x1a00
+#define SUBSI3 0x1e00
+#define SUBSI8 0x3800
+#define SUB_W 0xeba00000
+#define SUBWI 0xf2a00000
+#define SUB_SP 0xb080
+#define SUB_WI 0xf1a00000
+#define SXTB 0xb240
+#define SXTB_W 0xfa4ff080
+#define SXTH 0xb200
+#define SXTH_W 0xfa0ff080
+#define TST 0x4200
+#define UMULL 0xfba00000
+#define UXTB 0xb2c0
+#define UXTB_W 0xfa5ff080
+#define UXTH 0xb280
+#define UXTH_W 0xfa1ff080
+#define VABS_F32 0xeeb00ac0
+#define VADD_F32 0xee300a00
+#define VCMP_F32 0xeeb40a40
+#define VCVT_F32_S32 0xeeb80ac0
+#define VCVT_F64_F32 0xeeb70ac0
+#define VCVT_S32_F32 0xeebd0ac0
+#define VDIV_F32 0xee800a00
+#define VMOV_F32 0xeeb00a40
+#define VMOV 0xee000a10
+#define VMRS 0xeef1fa10
+#define VMUL_F32 0xee200a00
+#define VNEG_F32 0xeeb10a40
+#define VSTR_F32 0xed000a00
+#define VSUB_F32 0xee300a40
+
+static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst)
+{
+ sljit_u16 *ptr;
+ SLJIT_ASSERT(!(inst & 0xffff0000));
+
+ ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16));
+ FAIL_IF(!ptr);
+ *ptr = inst;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
+{
+ sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr++ = inst >> 16;
+ *ptr = inst;
+ compiler->size += 2;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
+{
+ FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
+ COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+ return push_inst32(compiler, MOVT | RD4(dst) |
+ COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+}
+
+static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
+{
+ sljit_s32 dst = inst[1] & 0x0f00;
+ SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));
+ inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1);
+ inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff);
+ inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1);
+ inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16);
+}
+
+static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
+{
+ sljit_sw diff;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+ if (jump->flags & JUMP_ADDR) {
+ /* Branch to ARM code is not optimized yet. */
+ if (!(jump->u.target & 0x1))
+ return 0;
+ diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset) >> 1;
+ }
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1;
+ }
+
+ if (jump->flags & IS_COND) {
+ SLJIT_ASSERT(!(jump->flags & IS_BL));
+ if (diff <= 127 && diff >= -128) {
+ jump->flags |= PATCH_TYPE1;
+ return 5;
+ }
+ if (diff <= 524287 && diff >= -524288) {
+ jump->flags |= PATCH_TYPE2;
+ return 4;
+ }
+ /* +1 comes from the prefix IT instruction. */
+ diff--;
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= PATCH_TYPE3;
+ return 3;
+ }
+ }
+ else if (jump->flags & IS_BL) {
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= PATCH_BL;
+ return 3;
+ }
+ }
+ else {
+ if (diff <= 1023 && diff >= -1024) {
+ jump->flags |= PATCH_TYPE4;
+ return 4;
+ }
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= PATCH_TYPE5;
+ return 3;
+ }
+ }
+
+ return 0;
+}
+
+static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset)
+{
+ sljit_s32 type = (jump->flags >> 4) & 0xf;
+ sljit_sw diff;
+ sljit_u16 *jump_inst;
+ sljit_s32 s, j1, j2;
+
+ if (SLJIT_UNLIKELY(type == 0)) {
+ modify_imm32_const((sljit_u16*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
+ return;
+ }
+
+ if (jump->flags & JUMP_ADDR) {
+ SLJIT_ASSERT(jump->u.target & 0x1);
+ diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
+ }
+ else {
+ SLJIT_ASSERT(jump->u.label->addr & 0x1);
+ diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
+ }
+ jump_inst = (sljit_u16*)jump->addr;
+
+ switch (type) {
+ case 1:
+ /* Encoding T1 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_COND));
+ jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff);
+ return;
+ case 2:
+ /* Encoding T3 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_COND));
+ jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1);
+ jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff);
+ return;
+ case 3:
+ SLJIT_ASSERT(jump->flags & IS_COND);
+ *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8;
+ diff--;
+ type = 5;
+ break;
+ case 4:
+ /* Encoding T2 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_COND));
+ jump_inst[0] = 0xe000 | (diff & 0x7ff);
+ return;
+ }
+
+ SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608);
+
+ /* Really complex instruction form for branches. */
+ s = (diff >> 23) & 0x1;
+ j1 = (~(diff >> 21) ^ s) & 0x1;
+ j2 = (~(diff >> 22) ^ s) & 0x1;
+ jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10);
+ jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff);
+
+ /* The others have a common form. */
+ if (type == 5) /* Encoding T4 of 'B' instruction */
+ jump_inst[1] |= 0x9000;
+ else if (type == 6) /* Encoding T1 of 'BL' instruction */
+ jump_inst[1] |= 0xd000;
+ else
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_u16 *code;
+ sljit_u16 *code_ptr;
+ sljit_u16 *buf_ptr;
+ sljit_u16 *buf_end;
+ sljit_uw half_count;
+ sljit_sw executable_offset;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ half_count = 0;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ do {
+ buf_ptr = (sljit_u16*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 1);
+ do {
+ *code_ptr = *buf_ptr++;
+ /* These structures are ordered by their address. */
+ SLJIT_ASSERT(!label || label->size >= half_count);
+ SLJIT_ASSERT(!jump || jump->addr >= half_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= half_count);
+ if (label && label->size == half_count) {
+ label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == half_count) {
+ jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
+ code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == half_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ half_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == half_count) {
+ label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ set_jump_instruction(jump, executable_offset);
+ jump = jump->next;
+ }
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
+
+ code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ /* Set thumb mode flag. */
+ return (void*)((sljit_uw)code | 0x1);
+}
+
+/* --------------------------------------------------------------------- */
+/* Core code generator functions. */
+/* --------------------------------------------------------------------- */
+
+#define INVALID_IMM 0x80000000
+static sljit_uw get_imm(sljit_uw imm)
+{
+ /* Thumb immediate form. */
+ sljit_s32 counter;
+
+ if (imm <= 0xff)
+ return imm;
+
+ if ((imm & 0xffff) == (imm >> 16)) {
+ /* Some special cases. */
+ if (!(imm & 0xff00))
+ return (1 << 12) | (imm & 0xff);
+ if (!(imm & 0xff))
+ return (2 << 12) | ((imm >> 8) & 0xff);
+ if ((imm & 0xff00) == ((imm & 0xff) << 8))
+ return (3 << 12) | (imm & 0xff);
+ }
+
+ /* Assembly optimization: count leading zeroes? */
+ counter = 8;
+ if (!(imm & 0xffff0000)) {
+ counter += 16;
+ imm <<= 16;
+ }
+ if (!(imm & 0xff000000)) {
+ counter += 8;
+ imm <<= 8;
+ }
+ if (!(imm & 0xf0000000)) {
+ counter += 4;
+ imm <<= 4;
+ }
+ if (!(imm & 0xc0000000)) {
+ counter += 2;
+ imm <<= 2;
+ }
+ if (!(imm & 0x80000000)) {
+ counter += 1;
+ imm <<= 1;
+ }
+ /* Since imm >= 128, this must be true. */
+ SLJIT_ASSERT(counter <= 31);
+
+ if (imm & 0x00ffffff)
+ return INVALID_IMM; /* Cannot be encoded. */
+
+ return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1);
+}
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
+{
+ sljit_uw tmp;
+
+ if (imm >= 0x10000) {
+ tmp = get_imm(imm);
+ if (tmp != INVALID_IMM)
+ return push_inst32(compiler, MOV_WI | RD4(dst) | tmp);
+ tmp = get_imm(~imm);
+ if (tmp != INVALID_IMM)
+ return push_inst32(compiler, MVN_WI | RD4(dst) | tmp);
+ }
+
+ /* set low 16 bits, set hi 16 bits to 0. */
+ FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
+ COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+
+ /* set hi 16 bit if needed. */
+ if (imm >= 0x10000)
+ return push_inst32(compiler, MOVT | RD4(dst) |
+ COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+ return SLJIT_SUCCESS;
+}
+
+#define ARG1_IMM 0x0010000
+#define ARG2_IMM 0x0020000
+#define KEEP_FLAGS 0x0040000
+/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */
+#define SET_FLAGS 0x0100000
+#define UNUSED_RETURN 0x0200000
+#define SLOW_DEST 0x0400000
+#define SLOW_SRC1 0x0800000
+#define SLOW_SRC2 0x1000000
+
+static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2)
+{
+ /* dst must be register, TMP_REG1
+ arg1 must be register, TMP_REG1, imm
+ arg2 must be register, TMP_REG2, imm */
+ sljit_s32 reg;
+ sljit_uw imm, nimm;
+
+ if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
+ /* Both are immediates. */
+ flags &= ~ARG1_IMM;
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+
+ if (flags & (ARG1_IMM | ARG2_IMM)) {
+ reg = (flags & ARG2_IMM) ? arg1 : arg2;
+ imm = (flags & ARG2_IMM) ? arg2 : arg1;
+
+ switch (flags & 0xffff) {
+ case SLJIT_CLZ:
+ case SLJIT_MUL:
+ /* No form with immediate operand. */
+ break;
+ case SLJIT_MOV:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
+ return load_immediate(compiler, dst, imm);
+ case SLJIT_NOT:
+ if (!(flags & SET_FLAGS))
+ return load_immediate(compiler, dst, ~imm);
+ /* Since the flags should be set, we just fallback to the register mode.
+ Although some clever things could be done here, "NOT IMM" does not worth the efforts. */
+ break;
+ case SLJIT_ADD:
+ nimm = -imm;
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) {
+ if (imm <= 0x7)
+ return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
+ if (nimm <= 0x7)
+ return push_inst16(compiler, SUBSI3 | IMM3(nimm) | RD3(dst) | RN3(reg));
+ if (reg == dst) {
+ if (imm <= 0xff)
+ return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst));
+ if (nimm <= 0xff)
+ return push_inst16(compiler, SUBSI8 | IMM8(nimm) | RDN3(dst));
+ }
+ }
+ if (!(flags & SET_FLAGS)) {
+ if (imm <= 0xfff)
+ return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm));
+ if (nimm <= 0xfff)
+ return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(nimm));
+ }
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_ADDC:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_SUB:
+ if (flags & ARG1_IMM) {
+ if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst))
+ return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg));
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ }
+ nimm = -imm;
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) {
+ if (imm <= 0x7)
+ return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
+ if (nimm <= 0x7)
+ return push_inst16(compiler, ADDSI3 | IMM3(nimm) | RD3(dst) | RN3(reg));
+ if (reg == dst) {
+ if (imm <= 0xff)
+ return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst));
+ if (nimm <= 0xff)
+ return push_inst16(compiler, ADDSI8 | IMM8(nimm) | RDN3(dst));
+ }
+ if (imm <= 0xff && (flags & UNUSED_RETURN))
+ return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg));
+ }
+ if (!(flags & SET_FLAGS)) {
+ if (imm <= 0xfff)
+ return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm));
+ if (nimm <= 0xfff)
+ return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(nimm));
+ }
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_SUBC:
+ if (flags & ARG1_IMM)
+ break;
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_AND:
+ nimm = get_imm(imm);
+ if (nimm != INVALID_IMM)
+ return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_OR:
+ nimm = get_imm(imm);
+ if (nimm != INVALID_IMM)
+ return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_XOR:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+ if (flags & ARG1_IMM)
+ break;
+ imm &= 0x1f;
+ if (imm == 0) {
+ if (!(flags & SET_FLAGS))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+ if (IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+ }
+ switch (flags & 0xffff) {
+ case SLJIT_SHL:
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ case SLJIT_LSHR:
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ default: /* SLJIT_ASHR */
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ }
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ if (flags & ARG2_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
+ arg2 = TMP_REG2;
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+ }
+
+ /* Both arguments are registers. */
+ switch (flags & 0xffff) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ case SLJIT_MOV_P:
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_U32:
+ case SLJIT_MOVU_S32:
+ case SLJIT_MOVU_P:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (dst == arg2)
+ return SLJIT_SUCCESS;
+ return push_inst16(compiler, MOV | SET_REGS44(dst, arg2));
+ case SLJIT_MOV_U8:
+ case SLJIT_MOVU_U8:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_S8:
+ case SLJIT_MOVU_S8:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_U16:
+ case SLJIT_MOVU_U16:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_S16:
+ case SLJIT_MOVU_S16:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2));
+ case SLJIT_NOT:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2));
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2)));
+ if (flags & SET_FLAGS) {
+ if (reg_map[dst] <= 7)
+ return push_inst16(compiler, CMPI | RDN3(dst));
+ return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst));
+ }
+ return SLJIT_SUCCESS;
+ case SLJIT_ADD:
+ if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+ return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2));
+ if (dst == arg1 && !(flags & SET_FLAGS))
+ return push_inst16(compiler, ADD | SET_REGS44(dst, arg2));
+ return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_ADDC:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SUB:
+ if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+ return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2));
+ return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SUBC:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_MUL:
+ if (!(flags & SET_FLAGS))
+ return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2));
+ SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2);
+ FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2)));
+ /* cmp TMP_REG2, dst asr #31. */
+ return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst));
+ case SLJIT_AND:
+ if (!(flags & KEEP_FLAGS)) {
+ if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));
+ if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2))
+ return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2));
+ }
+ return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_OR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_XOR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SHL:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_LSHR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_ASHR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+#define STORE 0x01
+#define SIGNED 0x02
+
+#define WORD_SIZE 0x00
+#define BYTE_SIZE 0x04
+#define HALF_SIZE 0x08
+
+#define UPDATE 0x10
+#define ARG_TEST 0x20
+
+#define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE)))
+#define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift)))
+
+/*
+ 1st letter:
+ w = word
+ b = byte
+ h = half
+
+ 2nd letter:
+ s = signed
+ u = unsigned
+
+ 3rd letter:
+ l = load
+ s = store
+*/
+
+static const sljit_ins sljit_mem16[12] = {
+/* w u l */ 0x5800 /* ldr */,
+/* w u s */ 0x5000 /* str */,
+/* w s l */ 0x5800 /* ldr */,
+/* w s s */ 0x5000 /* str */,
+
+/* b u l */ 0x5c00 /* ldrb */,
+/* b u s */ 0x5400 /* strb */,
+/* b s l */ 0x5600 /* ldrsb */,
+/* b s s */ 0x5400 /* strb */,
+
+/* h u l */ 0x5a00 /* ldrh */,
+/* h u s */ 0x5200 /* strh */,
+/* h s l */ 0x5e00 /* ldrsh */,
+/* h s s */ 0x5200 /* strh */,
+};
+
+static const sljit_ins sljit_mem16_imm5[12] = {
+/* w u l */ 0x6800 /* ldr imm5 */,
+/* w u s */ 0x6000 /* str imm5 */,
+/* w s l */ 0x6800 /* ldr imm5 */,
+/* w s s */ 0x6000 /* str imm5 */,
+
+/* b u l */ 0x7800 /* ldrb imm5 */,
+/* b u s */ 0x7000 /* strb imm5 */,
+/* b s l */ 0x0000 /* not allowed */,
+/* b s s */ 0x7000 /* strb imm5 */,
+
+/* h u l */ 0x8800 /* ldrh imm5 */,
+/* h u s */ 0x8000 /* strh imm5 */,
+/* h s l */ 0x0000 /* not allowed */,
+/* h s s */ 0x8000 /* strh imm5 */,
+};
+
+#define MEM_IMM8 0xc00
+#define MEM_IMM12 0x800000
+static const sljit_ins sljit_mem32[12] = {
+/* w u l */ 0xf8500000 /* ldr.w */,
+/* w u s */ 0xf8400000 /* str.w */,
+/* w s l */ 0xf8500000 /* ldr.w */,
+/* w s s */ 0xf8400000 /* str.w */,
+
+/* b u l */ 0xf8100000 /* ldrb.w */,
+/* b u s */ 0xf8000000 /* strb.w */,
+/* b s l */ 0xf9100000 /* ldrsb.w */,
+/* b s s */ 0xf8000000 /* strb.w */,
+
+/* h u l */ 0xf8300000 /* ldrh.w */,
+/* h u s */ 0xf8200000 /* strsh.w */,
+/* h s l */ 0xf9300000 /* ldrsh.w */,
+/* h s s */ 0xf8200000 /* strsh.w */,
+};
+
+/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
+static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
+{
+ if (value >= 0) {
+ if (value <= 0xfff)
+ return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value));
+ value = get_imm(value);
+ if (value != INVALID_IMM)
+ return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value);
+ }
+ else {
+ value = -value;
+ if (value <= 0xfff)
+ return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value));
+ value = get_imm(value);
+ if (value != INVALID_IMM)
+ return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value);
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+/* Can perform an operation using at most 1 instruction. */
+static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ sljit_s32 other_r, shift;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (SLJIT_UNLIKELY(flags & UPDATE)) {
+ if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 0xff && argw >= -0xff) {
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ flags &= ~UPDATE;
+ arg &= 0xf;
+ if (argw >= 0)
+ argw |= 0x200;
+ else {
+ argw = -argw;
+ }
+
+ SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff);
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw));
+ return -1;
+ }
+ return 0;
+ }
+
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ argw &= 0x3;
+ other_r = OFFS_REG(arg);
+ arg &= 0xf;
+
+ if (!argw && IS_3_LO_REGS(reg, arg, other_r))
+ FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r)));
+ else
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4)));
+ return -1;
+ }
+
+ if (!(arg & REG_MASK) || argw > 0xfff || argw < -0xff)
+ return 0;
+
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ arg &= 0xf;
+ if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) {
+ shift = 3;
+ if (IS_WORD_SIZE(flags)) {
+ if (OFFSET_CHECK(0x1f, 2))
+ shift = 2;
+ }
+ else if (flags & BYTE_SIZE)
+ {
+ if (OFFSET_CHECK(0x1f, 0))
+ shift = 0;
+ }
+ else {
+ SLJIT_ASSERT(flags & HALF_SIZE);
+ if (OFFSET_CHECK(0x1f, 1))
+ shift = 1;
+ }
+
+ if (shift != 3) {
+ FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - shift))));
+ return -1;
+ }
+ }
+
+ /* SP based immediate. */
+ if (SLJIT_UNLIKELY(arg == SLJIT_SP) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) {
+ FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2)));
+ return -1;
+ }
+
+ if (argw >= 0)
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
+ else
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw));
+ return -1;
+}
+
+/* see getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_sw diff;
+ if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
+ return 0;
+
+ if (!(arg & REG_MASK)) {
+ diff = argw - next_argw;
+ if (diff <= 0xfff && diff >= -0xfff)
+ return 1;
+ return 0;
+ }
+
+ if (argw == next_argw)
+ return 1;
+
+ diff = argw - next_argw;
+ if (arg == next_arg && diff <= 0xfff && diff >= -0xfff)
+ return 1;
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
+ sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_s32 tmp_r, other_r;
+ sljit_sw diff;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ tmp_r = (flags & STORE) ? TMP_REG3 : reg;
+
+ if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) {
+ /* Update only applies if a base register exists. */
+ /* There is no caching here. */
+ other_r = OFFS_REG(arg);
+ arg &= 0xf;
+ flags &= ~UPDATE;
+
+ if (!other_r) {
+ if (!(argw & ~0xfff)) {
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
+ return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw));
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM) {
+ if (argw == compiler->cache_argw) {
+ other_r = TMP_REG3;
+ argw = 0;
+ }
+ else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ other_r = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ if (argw) {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ other_r = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ argw &= 0x3;
+ if (!argw && IS_3_LO_REGS(reg, arg, other_r)) {
+ FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r)));
+ return push_inst16(compiler, ADD | SET_REGS44(arg, other_r));
+ }
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4)));
+ return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(other_r) | (argw << 6));
+ }
+ flags &= ~UPDATE;
+
+ SLJIT_ASSERT(!(arg & OFFS_REG_MASK));
+
+ if (compiler->cache_arg == arg) {
+ diff = argw - compiler->cache_argw;
+ if (!(diff & ~0xfff))
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | diff);
+ if (!((compiler->cache_argw - argw) & ~0xff))
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
+ }
+ }
+
+ next_arg = (arg & REG_MASK) && (arg == next_arg) && (argw != next_argw);
+ arg &= 0xf;
+ if (arg && compiler->cache_arg == SLJIT_MEM) {
+ if (compiler->cache_argw == argw)
+ return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
+ }
+ }
+
+ compiler->cache_argw = argw;
+ if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+
+ diff = argw - next_argw;
+ if (next_arg && diff <= 0xfff && diff >= -0xfff) {
+ FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg)));
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ }
+
+ if (arg)
+ return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ return compiler->error;
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 size, i, tmp;
+ sljit_ins push;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ push = (1 << 4);
+
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--)
+ push |= 1 << reg_map[i];
+
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
+ push |= 1 << reg_map[i];
+
+ FAIL_IF((push & 0xff00)
+ ? push_inst32(compiler, PUSH_W | (1 << 14) | push)
+ : push_inst16(compiler, PUSH | (1 << 8) | push));
+
+ /* Stack must be aligned to 8 bytes: (LR, R4) */
+ size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);
+ local_size = ((size + local_size + 7) & ~7) - size;
+ compiler->local_size = local_size;
+ if (local_size > 0) {
+ if (local_size <= (127 << 2))
+ FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2)));
+ else
+ FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size));
+ }
+
+ if (args >= 1)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0, SLJIT_R0)));
+ if (args >= 2)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S1, SLJIT_R1)));
+ if (args >= 3)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S2, SLJIT_R2)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 size;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);
+ compiler->local_size = ((size + local_size + 7) & ~7) - size;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 i, tmp;
+ sljit_ins pop;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0) {
+ if (compiler->local_size <= (127 << 2))
+ FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2)));
+ else
+ FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_SP, SLJIT_SP, compiler->local_size));
+ }
+
+ pop = (1 << 4);
+
+ tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--)
+ pop |= 1 << reg_map[i];
+
+ for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
+ pop |= 1 << reg_map[i];
+
+ return (pop & 0xff00)
+ ? push_inst32(compiler, POP_W | (1 << 15) | pop)
+ : push_inst16(compiler, POP | (1 << 8) | pop);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__)
+extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator);
+extern int __aeabi_idivmod(int numerator, int denominator);
+#else
+#error "Software divmod functions are needed"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ sljit_sw saved_reg_list[3];
+ sljit_sw saved_reg_count;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ return push_inst16(compiler, BKPT);
+ case SLJIT_NOP:
+ return push_inst16(compiler, NOP);
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+ return push_inst32(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
+ | (reg_map[SLJIT_R1] << 8)
+ | (reg_map[SLJIT_R0] << 12)
+ | (reg_map[SLJIT_R0] << 16)
+ | reg_map[SLJIT_R1]);
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+ SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
+ SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping);
+
+ saved_reg_count = 0;
+ if (compiler->scratches >= 4)
+ saved_reg_list[saved_reg_count++] = 12;
+ if (compiler->scratches >= 3)
+ saved_reg_list[saved_reg_count++] = 2;
+ if (op >= SLJIT_DIV_UW)
+ saved_reg_list[saved_reg_count++] = 1;
+
+ if (saved_reg_count > 0) {
+ FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8)
+ | (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));
+ if (saved_reg_count >= 2) {
+ SLJIT_ASSERT(saved_reg_list[1] < 8);
+ FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */));
+ }
+ if (saved_reg_count >= 3) {
+ SLJIT_ASSERT(saved_reg_list[2] < 8);
+ FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */));
+ }
+ }
+
+#if defined(__GNUC__)
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
+ ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
+#else
+#error "Software divmod functions are needed"
+#endif
+
+ if (saved_reg_count > 0) {
+ if (saved_reg_count >= 3) {
+ SLJIT_ASSERT(saved_reg_list[2] < 8);
+ FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */));
+ }
+ if (saved_reg_count >= 2) {
+ SLJIT_ASSERT(saved_reg_list[1] < 8);
+ FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */));
+ }
+ return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)
+ | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r, flags;
+ sljit_s32 op_flags = GET_ALL_FLAGS(op);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+
+ op = GET_OPCODE(op);
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ case SLJIT_MOV_P:
+ flags = WORD_SIZE;
+ break;
+ case SLJIT_MOV_U8:
+ flags = BYTE_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u8)srcw;
+ break;
+ case SLJIT_MOV_S8:
+ flags = BYTE_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s8)srcw;
+ break;
+ case SLJIT_MOV_U16:
+ flags = HALF_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u16)srcw;
+ break;
+ case SLJIT_MOV_S16:
+ flags = HALF_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s16)srcw;
+ break;
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_U32:
+ case SLJIT_MOVU_S32:
+ case SLJIT_MOVU_P:
+ flags = WORD_SIZE | UPDATE;
+ break;
+ case SLJIT_MOVU_U8:
+ flags = BYTE_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u8)srcw;
+ break;
+ case SLJIT_MOVU_S8:
+ flags = BYTE_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s8)srcw;
+ break;
+ case SLJIT_MOVU_U16:
+ flags = HALF_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_u16)srcw;
+ break;
+ case SLJIT_MOVU_S16:
+ flags = HALF_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s16)srcw;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ flags = 0;
+ break;
+ }
+
+ if (src & SLJIT_IMM)
+ FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
+ } else {
+ if (dst_r != TMP_REG1)
+ return emit_op_imm(compiler, op, dst_r, TMP_REG1, src);
+ dst_r = src;
+ }
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (op == SLJIT_NEG) {
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, SLJIT_SUB | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw);
+ }
+
+ flags = (GET_FLAGS(op_flags) ? SET_FLAGS : 0) | ((op_flags & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
+ if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw));
+ src = TMP_REG2;
+ }
+
+ if (src & SLJIT_IMM)
+ flags |= ARG2_IMM;
+ else
+ srcw = src;
+
+ emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw);
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r, flags;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+ flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
+
+ if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ }
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
+
+ if (src1 & SLJIT_MEM)
+ src1 = TMP_REG1;
+ if (src2 & SLJIT_MEM)
+ src2 = TMP_REG2;
+
+ if (src1 & SLJIT_IMM)
+ flags |= ARG1_IMM;
+ else
+ src1w = src1;
+ if (src2 & SLJIT_IMM)
+ flags |= ARG2_IMM;
+ else
+ src2w = src2;
+
+ if (dst == SLJIT_UNUSED)
+ flags |= UNUSED_RETURN;
+
+ emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ return reg << 1;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ if (size == 2)
+ return push_inst16(compiler, *(sljit_u16*)instruction);
+ return push_inst32(compiler, *(sljit_ins*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+#ifdef SLJIT_IS_FPU_AVAILABLE
+ return SLJIT_IS_FPU_AVAILABLE;
+#else
+ /* Available by default. */
+ return 1;
+#endif
+}
+
+#define FPU_LOAD (1 << 20)
+
+static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ sljit_sw tmp;
+ sljit_uw imm;
+ sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD));
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((argw & 0x3) << 6)));
+ arg = SLJIT_MEM | TMP_REG2;
+ argw = 0;
+ }
+
+ if ((arg & REG_MASK) && (argw & 0x3) == 0) {
+ if (!(argw & ~0x3fc))
+ return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | (argw >> 2));
+ if (!(-argw & ~0x3fc))
+ return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | (-argw >> 2));
+ }
+
+ /* Slow cases */
+ SLJIT_ASSERT(!(arg & OFFS_REG_MASK));
+ if (compiler->cache_arg == arg) {
+ tmp = argw - compiler->cache_argw;
+ if (!(tmp & ~0x3fc))
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2));
+ if (!(-tmp & ~0x3fc))
+ return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
+ }
+ }
+
+ if (arg & REG_MASK) {
+ if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg));
+ }
+ imm = get_imm(argw & ~0x3fc);
+ if (imm != INVALID_IMM) {
+ FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2));
+ }
+ imm = get_imm(-argw & ~0x3fc);
+ if (imm != INVALID_IMM) {
+ argw = -argw;
+ FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));
+ return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2));
+ }
+ }
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ if (arg & REG_MASK)
+ FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & REG_MASK))));
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
+ src = TMP_FREG1;
+ }
+
+ FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_F32_OP) | DD4(TMP_FREG1) | DM4(src)));
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1));
+
+ /* Store the integer value from a VFP register. */
+ return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1)));
+ else if (src & SLJIT_MEM) {
+ /* Load the integer value into a VFP register. */
+ FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+ FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1)));
+ }
+
+ FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(TMP_FREG1)));
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (src1 & SLJIT_MEM) {
+ emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
+ src1 = TMP_FREG1;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);
+ src2 = TMP_FREG2;
+ }
+
+ FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_F32_OP) | DD4(src1) | DM4(src2)));
+ return push_inst32(compiler, VMRS);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
+ op ^= SLJIT_F32_OP;
+
+ SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error);
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (src & SLJIT_MEM) {
+ emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw);
+ src = dst_r;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_F64:
+ if (src != dst_r) {
+ if (dst_r != TMP_FREG1)
+ FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
+ else
+ dst_r = src;
+ }
+ break;
+ case SLJIT_NEG_F64:
+ FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
+ break;
+ case SLJIT_ABS_F64:
+ FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
+ break;
+ case SLJIT_CONV_F64_FROM_F32:
+ FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
+ op ^= SLJIT_F32_OP;
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ op ^= SLJIT_F32_OP;
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+ if (src1 & SLJIT_MEM) {
+ emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
+ src1 = TMP_FREG1;
+ }
+ if (src2 & SLJIT_MEM) {
+ emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);
+ src2 = TMP_FREG2;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD_F64:
+ FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_SUB_F64:
+ FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_MUL_F64:
+ FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_DIV_F64:
+ FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ }
+
+ if (!(dst & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);
+}
+
+#undef FPU_LOAD
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3));
+
+ /* Memory. */
+ if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw))
+ return compiler->error;
+ /* TMP_REG3 is used for caching. */
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3)));
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src)));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw))
+ FAIL_IF(compiler->error);
+ else {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0));
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2)));
+ }
+ }
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
+ return push_inst16(compiler, BLX | RN3(TMP_REG3));
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+static sljit_uw get_cc(sljit_s32 type)
+{
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ case SLJIT_EQUAL_F64:
+ return 0x0;
+
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_NOT_EQUAL_F64:
+ return 0x1;
+
+ case SLJIT_LESS:
+ case SLJIT_LESS_F64:
+ return 0x3;
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ return 0x2;
+
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_F64:
+ return 0x8;
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return 0x9;
+
+ case SLJIT_SIG_LESS:
+ return 0xb;
+
+ case SLJIT_SIG_GREATER_EQUAL:
+ return 0xa;
+
+ case SLJIT_SIG_GREATER:
+ return 0xc;
+
+ case SLJIT_SIG_LESS_EQUAL:
+ return 0xd;
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_UNORDERED_F64:
+ return 0x6;
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_ORDERED_F64:
+ return 0x7;
+
+ default: /* SLJIT_JUMP */
+ SLJIT_ASSERT_STOP();
+ return 0xe;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ struct sljit_jump *jump;
+ sljit_ins cc;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In ARM, we don't need to touch the arguments. */
+ PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
+ if (type < SLJIT_JUMP) {
+ jump->flags |= IS_COND;
+ cc = get_cc(type);
+ jump->flags |= cc << 8;
+ PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ }
+
+ jump->addr = compiler->size;
+ if (type <= SLJIT_JUMP)
+ PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1)));
+ else {
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));
+ }
+
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ /* In ARM, we don't need to touch the arguments. */
+ if (!(src & SLJIT_IMM)) {
+ if (FAST_IS_REG(src))
+ return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
+
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw));
+ if (type >= SLJIT_FAST_CALL)
+ return push_inst16(compiler, BLX | RN3(TMP_REG1));
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
+ jump->u.target = srcw;
+
+ FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
+ jump->addr = compiler->size;
+ return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ sljit_s32 dst_r, flags = GET_ALL_FLAGS(op);
+ sljit_ins cc, ins;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ op = GET_OPCODE(op);
+ cc = get_cc(type & 0xff);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ if (op < SLJIT_ADD) {
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
+ if (reg_map[dst_r] > 7) {
+ FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1));
+ FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0));
+ } else {
+ FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1));
+ FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0));
+ }
+ if (dst_r != TMP_REG2)
+ return SLJIT_SUCCESS;
+ return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw);
+ }
+
+ ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI));
+ if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) {
+ /* Does not change the other bits. */
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1));
+ if (flags & SLJIT_SET_E) {
+ /* The condition must always be set, even if the ORRI/EORI is not executed above. */
+ if (reg_map[dst] <= 7)
+ return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst));
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw));
+ src = TMP_REG2;
+ srcw = 0;
+ } else if (src & SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
+ src = TMP_REG2;
+ srcw = 0;
+ }
+
+ if (op == SLJIT_AND || src != dst_r) {
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
+ FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1));
+ FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0));
+ }
+ else {
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1));
+ }
+
+ if (dst_r == TMP_REG2)
+ FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0));
+
+ if (flags & SLJIT_SET_E) {
+ /* The condition must always be set, even if the ORR/EORI is not executed above. */
+ if (reg_map[dst_r] <= 7)
+ return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r));
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_const *const_;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+ PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ sljit_u16 *inst = (sljit_u16*)addr;
+ modify_imm32_const(inst, new_target);
+ inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 4);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_u16 *inst = (sljit_u16*)addr;
+ modify_imm32_const(inst, new_constant);
+ inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 4);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
new file mode 100644
index 0000000000..b15a57dfdb
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
@@ -0,0 +1,368 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* mips 32-bit arch dependent functions. */
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
+{
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ if (imm < 0 && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
+}
+
+#define EMIT_LOGICAL(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
+ } \
+ else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
+ }
+
+#define EMIT_SHIFT(op_imm, op_v) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
+ } \
+ else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \
+ }
+
+static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
+{
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ case SLJIT_MOV_P:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (dst != src2)
+ return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S8) {
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+ return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
+#endif
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S16) {
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+ return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
+#endif
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
+#else
+ if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
+ FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
+ return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
+ }
+ /* Nearly all instructions are unmovable in the following sequence. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ /* Check zero. */
+ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst) | IMM(-1), DR(dst)));
+ /* Loop for searching the highest bit. */
+ FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst)));
+ FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
+ if (op & SLJIT_SET_E)
+ return push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
+#endif
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ADD:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ else
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
+ if (op & (SLJIT_SET_C | SLJIT_SET_O)) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ else {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ }
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & (SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ /* a + b >= a | b (otherwise, the carry should be set to 1). */
+ if (op & (SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (!(op & SLJIT_SET_O))
+ return SLJIT_SUCCESS;
+ FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+
+ case SLJIT_ADDC:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+ else {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ }
+ }
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ } else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+
+ FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+ if (!(op & SLJIT_SET_C))
+ return SLJIT_SUCCESS;
+
+ /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ /* Set carry flag. */
+ return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG);
+
+ case SLJIT_SUB:
+ if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ else
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
+ if (op & (SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (op & SLJIT_SET_U)
+ FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
+ if (op & SLJIT_SET_S) {
+ FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
+ FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (!(op & SLJIT_SET_O))
+ return SLJIT_SUCCESS;
+ FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+
+ case SLJIT_SUBC:
+ if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG));
+
+ FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+ return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
+
+ case SLJIT_MUL:
+ SLJIT_ASSERT(!(flags & SRC2_IMM));
+ if (!(op & SLJIT_SET_O)) {
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+ return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
+ return push_inst(compiler, MFLO | D(dst), DR(dst));
+#endif
+ }
+ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
+ FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG));
+ return push_inst(compiler, SUBU | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+
+ case SLJIT_AND:
+ EMIT_LOGICAL(ANDI, AND);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_OR:
+ EMIT_LOGICAL(ORI, OR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_XOR:
+ EMIT_LOGICAL(XORI, XOR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_SHL:
+ EMIT_SHIFT(SLL, SLLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT(SRL, SRLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT(SRA, SRAV);
+ return SLJIT_SUCCESS;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
+{
+ FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));
+ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c
new file mode 100644
index 0000000000..8b96d5b73d
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c
@@ -0,0 +1,471 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* mips 64-bit arch dependent functions. */
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
+{
+ sljit_s32 shift = 32;
+ sljit_s32 shift2;
+ sljit_s32 inv = 0;
+ sljit_ins ins;
+ sljit_uw uimm;
+
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ if (imm < 0 && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
+ FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
+ }
+
+ /* Zero extended number. */
+ uimm = imm;
+ if (imm < 0) {
+ uimm = ~imm;
+ inv = 1;
+ }
+
+ while (!(uimm & 0xff00000000000000l)) {
+ shift -= 8;
+ uimm <<= 8;
+ }
+
+ if (!(uimm & 0xf000000000000000l)) {
+ shift -= 4;
+ uimm <<= 4;
+ }
+
+ if (!(uimm & 0xc000000000000000l)) {
+ shift -= 2;
+ uimm <<= 2;
+ }
+
+ if ((sljit_sw)uimm < 0) {
+ uimm >>= 1;
+ shift += 1;
+ }
+ SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32));
+
+ if (inv)
+ uimm = ~uimm;
+
+ FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar));
+ if (uimm & 0x0000ffff00000000l)
+ FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar));
+
+ imm &= (1l << shift) - 1;
+ if (!(imm & ~0xffff)) {
+ ins = (shift == 32) ? DSLL32 : DSLL;
+ if (shift < 32)
+ ins |= SH_IMM(shift);
+ FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar));
+ return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);
+ }
+
+ /* Double shifts needs to be performed. */
+ uimm <<= 32;
+ shift2 = shift - 16;
+
+ while (!(uimm & 0xf000000000000000l)) {
+ shift2 -= 4;
+ uimm <<= 4;
+ }
+
+ if (!(uimm & 0xc000000000000000l)) {
+ shift2 -= 2;
+ uimm <<= 2;
+ }
+
+ if (!(uimm & 0x8000000000000000l)) {
+ shift2--;
+ uimm <<= 1;
+ }
+
+ SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16));
+
+ FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar));
+ FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar));
+ FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar));
+
+ imm &= (1l << shift2) - 1;
+ return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);
+}
+
+#define SELECT_OP(a, b) \
+ (!(op & SLJIT_I32_OP) ? a : b)
+
+#define EMIT_LOGICAL(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
+ } \
+ else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
+ }
+
+#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \
+ if (flags & SRC2_IMM) { \
+ if (src2 >= 32) { \
+ SLJIT_ASSERT(!(op & SLJIT_I32_OP)); \
+ ins = op_dimm32; \
+ src2 -= 32; \
+ } \
+ else \
+ ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
+ } \
+ else { \
+ ins = (op & SLJIT_I32_OP) ? op_v : op_dv; \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \
+ }
+
+static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
+{
+ sljit_ins ins;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (dst != src2)
+ return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S8) {
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
+ return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S16) {
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
+ return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U32:
+ SLJIT_ASSERT(!(op & SLJIT_I32_OP));
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
+ return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
+
+ case SLJIT_MOV_S32:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst)));
+#else
+ if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
+ return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
+ }
+ /* Nearly all instructions are unmovable in the following sequence. */
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ /* Check zero. */
+ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_I32_OP) ? 32 : 64), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst)));
+ /* Loop for searching the highest bit. */
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst)));
+ FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
+ if (op & SLJIT_SET_E)
+ return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
+#endif
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ADD:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ else
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
+ if (op & (SLJIT_SET_C | SLJIT_SET_O)) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ else {
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ }
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & (SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ /* a + b >= a | b (otherwise, the carry should be set to 1). */
+ if (op & (SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (!(op & SLJIT_SET_O))
+ return SLJIT_SUCCESS;
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+
+ case SLJIT_ADDC:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+ else {
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ }
+ }
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ } else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+ if (!(op & SLJIT_SET_C))
+ return SLJIT_SUCCESS;
+
+ /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ /* Set carry flag. */
+ return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG);
+
+ case SLJIT_SUB:
+ if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ else
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
+ if (op & (SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (op & SLJIT_SET_U)
+ FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
+ if (op & SLJIT_SET_S) {
+ FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
+ FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (!(op & SLJIT_SET_O))
+ return SLJIT_SUCCESS;
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+
+ case SLJIT_SUBC:
+ if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG));
+
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+ return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
+
+ case SLJIT_MUL:
+ SLJIT_ASSERT(!(flags & SRC2_IMM));
+ if (!(op & SLJIT_SET_O)) {
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+ if (op & SLJIT_I32_OP)
+ return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
+ FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
+ return push_inst(compiler, MFLO | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
+ return push_inst(compiler, MFLO | D(dst), DR(dst));
+#endif
+ }
+ FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG));
+ return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+
+ case SLJIT_AND:
+ EMIT_LOGICAL(ANDI, AND);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_OR:
+ EMIT_LOGICAL(ORI, OR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_XOR:
+ EMIT_LOGICAL(XORI, XOR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_SHL:
+ EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);
+ return SLJIT_SUCCESS;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
+{
+ FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst)));
+ FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst)));
+ FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
+ FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst)));
+ FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
+ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+ inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 6);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 6);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
new file mode 100644
index 0000000000..fe37e3ef00
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
@@ -0,0 +1,2147 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Latest MIPS architecture. */
+/* Automatically detect SLJIT_MIPS_R1 */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ return "MIPS32-R1" SLJIT_CPUINFO;
+#else
+ return "MIPS64-R1" SLJIT_CPUINFO;
+#endif
+#else /* SLJIT_MIPS_R1 */
+ return "MIPS III" SLJIT_CPUINFO;
+#endif
+}
+
+/* Length of an instruction word
+ Both for mips-32 and mips-64 */
+typedef sljit_u32 sljit_ins;
+
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+
+/* For position independent code, t9 must contain the function address. */
+#define PIC_ADDR_REG TMP_REG2
+
+/* Floating point status register. */
+#define FCSR_REG 31
+/* Return address register. */
+#define RETURN_ADDR_REG 31
+
+/* Flags are kept in volatile registers. */
+#define EQUAL_FLAG 12
+/* And carry flag as well. */
+#define ULESS_FLAG 13
+#define UGREATER_FLAG 14
+#define LESS_FLAG 15
+#define GREATER_FLAG 31
+#define OVERFLOW_FLAG 1
+
+#define TMP_FREG1 (0)
+#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
+ 0, 2, 5, 6, 7, 8, 9, 10, 11, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4
+};
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+#define S(s) (reg_map[s] << 21)
+#define T(t) (reg_map[t] << 16)
+#define D(d) (reg_map[d] << 11)
+/* Absolute registers. */
+#define SA(s) ((s) << 21)
+#define TA(t) ((t) << 16)
+#define DA(d) ((d) << 11)
+#define FT(t) ((t) << 16)
+#define FS(s) ((s) << 11)
+#define FD(d) ((d) << 6)
+#define IMM(imm) ((imm) & 0xffff)
+#define SH_IMM(imm) ((imm) << 6)
+
+#define DR(dr) (reg_map[dr])
+#define HI(opcode) ((opcode) << 26)
+#define LO(opcode) (opcode)
+/* S = (16 << 21) D = (17 << 21) */
+#define FMT_S (16 << 21)
+
+#define ABS_S (HI(17) | FMT_S | LO(5))
+#define ADD_S (HI(17) | FMT_S | LO(0))
+#define ADDIU (HI(9))
+#define ADDU (HI(0) | LO(33))
+#define AND (HI(0) | LO(36))
+#define ANDI (HI(12))
+#define B (HI(4))
+#define BAL (HI(1) | (17 << 16))
+#define BC1F (HI(17) | (8 << 21))
+#define BC1T (HI(17) | (8 << 21) | (1 << 16))
+#define BEQ (HI(4))
+#define BGEZ (HI(1) | (1 << 16))
+#define BGTZ (HI(7))
+#define BLEZ (HI(6))
+#define BLTZ (HI(1) | (0 << 16))
+#define BNE (HI(5))
+#define BREAK (HI(0) | LO(13))
+#define CFC1 (HI(17) | (2 << 21))
+#define C_UN_S (HI(17) | FMT_S | LO(49))
+#define C_UEQ_S (HI(17) | FMT_S | LO(51))
+#define C_ULE_S (HI(17) | FMT_S | LO(55))
+#define C_ULT_S (HI(17) | FMT_S | LO(53))
+#define CVT_S_S (HI(17) | FMT_S | LO(32))
+#define DADDIU (HI(25))
+#define DADDU (HI(0) | LO(45))
+#define DDIV (HI(0) | LO(30))
+#define DDIVU (HI(0) | LO(31))
+#define DIV (HI(0) | LO(26))
+#define DIVU (HI(0) | LO(27))
+#define DIV_S (HI(17) | FMT_S | LO(3))
+#define DMULT (HI(0) | LO(28))
+#define DMULTU (HI(0) | LO(29))
+#define DSLL (HI(0) | LO(56))
+#define DSLL32 (HI(0) | LO(60))
+#define DSLLV (HI(0) | LO(20))
+#define DSRA (HI(0) | LO(59))
+#define DSRA32 (HI(0) | LO(63))
+#define DSRAV (HI(0) | LO(23))
+#define DSRL (HI(0) | LO(58))
+#define DSRL32 (HI(0) | LO(62))
+#define DSRLV (HI(0) | LO(22))
+#define DSUBU (HI(0) | LO(47))
+#define J (HI(2))
+#define JAL (HI(3))
+#define JALR (HI(0) | LO(9))
+#define JR (HI(0) | LO(8))
+#define LD (HI(55))
+#define LUI (HI(15))
+#define LW (HI(35))
+#define MFC1 (HI(17))
+#define MFHI (HI(0) | LO(16))
+#define MFLO (HI(0) | LO(18))
+#define MOV_S (HI(17) | FMT_S | LO(6))
+#define MTC1 (HI(17) | (4 << 21))
+#define MUL_S (HI(17) | FMT_S | LO(2))
+#define MULT (HI(0) | LO(24))
+#define MULTU (HI(0) | LO(25))
+#define NEG_S (HI(17) | FMT_S | LO(7))
+#define NOP (HI(0) | LO(0))
+#define NOR (HI(0) | LO(39))
+#define OR (HI(0) | LO(37))
+#define ORI (HI(13))
+#define SD (HI(63))
+#define SLT (HI(0) | LO(42))
+#define SLTI (HI(10))
+#define SLTIU (HI(11))
+#define SLTU (HI(0) | LO(43))
+#define SLL (HI(0) | LO(0))
+#define SLLV (HI(0) | LO(4))
+#define SRL (HI(0) | LO(2))
+#define SRLV (HI(0) | LO(6))
+#define SRA (HI(0) | LO(3))
+#define SRAV (HI(0) | LO(7))
+#define SUB_S (HI(17) | FMT_S | LO(1))
+#define SUBU (HI(0) | LO(35))
+#define SW (HI(43))
+#define TRUNC_W_S (HI(17) | FMT_S | LO(13))
+#define XOR (HI(0) | LO(38))
+#define XORI (HI(14))
+
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#define CLZ (HI(28) | LO(32))
+#define DCLZ (HI(28) | LO(36))
+#define MUL (HI(28) | LO(2))
+#define SEB (HI(31) | (16 << 6) | LO(32))
+#define SEH (HI(31) | (24 << 6) | LO(32))
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define ADDU_W ADDU
+#define ADDIU_W ADDIU
+#define SLL_W SLL
+#define SUBU_W SUBU
+#else
+#define ADDU_W DADDU
+#define ADDIU_W DADDIU
+#define SLL_W DSLL
+#define SUBU_W DSUBU
+#endif
+
+#define SIMM_MAX (0x7fff)
+#define SIMM_MIN (-0x8000)
+#define UIMM_MAX (0xffff)
+
+/* dest_reg is the absolute name of the register
+ Useful for reordering instructions in the delay slot. */
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
+{
+ SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
+ || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f));
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ compiler->delay_slot = delay_slot;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)
+{
+ return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
+}
+
+static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+{
+ sljit_sw diff;
+ sljit_uw target_addr;
+ sljit_ins *inst;
+ sljit_ins saved_inst;
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
+ return code_ptr;
+#else
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return code_ptr;
+#endif
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
+ }
+
+ inst = (sljit_ins *)jump->addr;
+ if (jump->flags & IS_COND)
+ inst--;
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ if (jump->flags & IS_CALL)
+ goto keep_address;
+#endif
+
+ /* B instructions. */
+ if (jump->flags & IS_MOVABLE) {
+ diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ jump->flags |= PATCH_B;
+
+ if (!(jump->flags & IS_COND)) {
+ inst[0] = inst[-1];
+ inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+ saved_inst = inst[0];
+ inst[0] = inst[-1];
+ inst[-1] = saved_inst ^ invert_branch(jump->flags);
+ jump->addr -= 2 * sizeof(sljit_ins);
+ return inst;
+ }
+ }
+ else {
+ diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ jump->flags |= PATCH_B;
+
+ if (!(jump->flags & IS_COND)) {
+ inst[0] = (jump->flags & IS_JAL) ? BAL : B;
+ inst[1] = NOP;
+ return inst + 1;
+ }
+ inst[0] = inst[0] ^ invert_branch(jump->flags);
+ inst[1] = NOP;
+ jump->addr -= sizeof(sljit_ins);
+ return inst + 1;
+ }
+ }
+
+ if (jump->flags & IS_COND) {
+ if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ saved_inst = inst[0];
+ inst[0] = inst[-1];
+ inst[-1] = (saved_inst & 0xffff0000) | 3;
+ inst[1] = J;
+ inst[2] = NOP;
+ return inst + 2;
+ }
+ else if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = (inst[0] & 0xffff0000) | 3;
+ inst[1] = NOP;
+ inst[2] = J;
+ inst[3] = NOP;
+ jump->addr += sizeof(sljit_ins);
+ return inst + 3;
+ }
+ }
+ else {
+ /* J instuctions. */
+ if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = inst[-1];
+ inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+
+ if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = (jump->flags & IS_JAL) ? JAL : J;
+ inst[1] = NOP;
+ return inst + 1;
+ }
+ }
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+keep_address:
+ if (target_addr <= 0x7fffffff) {
+ jump->flags |= PATCH_ABS32;
+ if (jump->flags & IS_COND) {
+ inst[0] -= 4;
+ inst++;
+ }
+ inst[2] = inst[6];
+ inst[3] = inst[7];
+ return inst + 3;
+ }
+ if (target_addr <= 0x7fffffffffffl) {
+ jump->flags |= PATCH_ABS48;
+ if (jump->flags & IS_COND) {
+ inst[0] -= 2;
+ inst++;
+ }
+ inst[4] = inst[6];
+ inst[5] = inst[7];
+ return inst + 5;
+ }
+#endif
+
+ return code_ptr;
+}
+
+#ifdef __GNUC__
+static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
+{
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_sw executable_offset;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ jump->addr = (sljit_uw)(code_ptr - 3);
+#else
+ jump->addr = (sljit_uw)(code_ptr - 7);
+#endif
+ code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins *)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ addr = (sljit_sw)(addr - ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins))) >> 2;
+ SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff);
+ break;
+ }
+ if (jump->flags & PATCH_J) {
+ SLJIT_ASSERT((addr & ~0xfffffff) == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~0xfffffff));
+ buf_ptr[0] |= (addr >> 2) & 0x03ffffff;
+ break;
+ }
+
+ /* Set the fields of immediate loads. */
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+#else
+ if (jump->flags & PATCH_ABS32) {
+ SLJIT_ASSERT(addr <= 0x7fffffff);
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+ }
+ else if (jump->flags & PATCH_ABS48) {
+ SLJIT_ASSERT(addr <= 0x7fffffffffffl);
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);
+ }
+ else {
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[5] = (buf_ptr[5] & 0xffff0000) | (addr & 0xffff);
+ }
+#endif
+ } while (0);
+ jump = jump->next;
+ }
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+
+ code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+#ifndef __GNUC__
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+#else
+ /* GCC workaround for invalid code generation with -O2. */
+ sljit_cache_flush(code, code_ptr);
+#endif
+ return code;
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+/* Creates an index in data_transfer_insts array. */
+#define LOAD_DATA 0x01
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x02
+#define HALF_DATA 0x04
+#define INT_DATA 0x06
+#define SIGNED_DATA 0x08
+/* Separates integer and floating point registers */
+#define GPR_REG 0x0f
+#define DOUBLE_DATA 0x10
+#define SINGLE_DATA 0x12
+
+#define MEM_MASK 0x1f
+
+#define WRITE_BACK 0x00020
+#define ARG_TEST 0x00040
+#define ALT_KEEP_CACHE 0x00080
+#define CUMULATIVE_OP 0x00100
+#define LOGICAL_OP 0x00200
+#define IMM_OP 0x00400
+#define SRC2_IMM 0x00800
+
+#define UNUSED_DEST 0x01000
+#define REG_DEST 0x02000
+#define REG1_SOURCE 0x04000
+#define REG2_SOURCE 0x08000
+#define SLOW_SRC1 0x10000
+#define SLOW_SRC2 0x20000
+#define SLOW_DEST 0x40000
+
+/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */
+#define CHECK_FLAGS(list) \
+ (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define STACK_STORE SW
+#define STACK_LOAD LW
+#else
+#define STACK_STORE SD
+#define STACK_LOAD LD
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#include "sljitNativeMIPS_32.c"
+#else
+#include "sljitNativeMIPS_64.c"
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_ins base;
+ sljit_s32 i, tmp, offs;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ local_size = (local_size + 15) & ~0xf;
+#else
+ local_size = (local_size + 31) & ~0x1f;
+#endif
+ compiler->local_size = local_size;
+
+ if (local_size <= SIMM_MAX) {
+ /* Frequent case. */
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
+ base = S(SLJIT_SP);
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
+ base = S(TMP_REG2);
+ local_size = 0;
+ }
+
+ offs = local_size - (sljit_sw)(sizeof(sljit_sw));
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS));
+
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--) {
+ offs -= (sljit_s32)(sizeof(sljit_sw));
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS));
+ }
+
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
+ offs -= (sljit_s32)(sizeof(sljit_sw));
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS));
+ }
+
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_S0), DR(SLJIT_S0)));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_S1), DR(SLJIT_S1)));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_S2), DR(SLJIT_S2)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ compiler->local_size = (local_size + 15) & ~0xf;
+#else
+ compiler->local_size = (local_size + 31) & ~0x1f;
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 local_size, i, tmp, offs;
+ sljit_ins base;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ local_size = compiler->local_size;
+ if (local_size <= SIMM_MAX)
+ base = S(SLJIT_SP);
+ else {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1)));
+ base = S(TMP_REG1);
+ local_size = 0;
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_s32)sizeof(sljit_sw)), RETURN_ADDR_REG));
+ offs = local_size - (sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
+
+ tmp = compiler->scratches;
+ for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i)));
+ offs += (sljit_s32)(sizeof(sljit_sw));
+ }
+
+ tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = tmp; i <= SLJIT_S0; i++) {
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i)));
+ offs += (sljit_s32)(sizeof(sljit_sw));
+ }
+
+ SLJIT_ASSERT(offs == local_size - (sljit_sw)(sizeof(sljit_sw)));
+
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ if (compiler->local_size <= SIMM_MAX)
+ return push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(compiler->local_size), UNMOVABLE_INS);
+ else
+ return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_SP), UNMOVABLE_INS);
+}
+
+#undef STACK_STORE
+#undef STACK_LOAD
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define ARCH_32_64(a, b) a
+#else
+#define ARCH_32_64(a, b) b
+#endif
+
+static const sljit_ins data_transfer_insts[16 + 4] = {
+/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
+/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
+/* u b s */ HI(40) /* sb */,
+/* u b l */ HI(36) /* lbu */,
+/* u h s */ HI(41) /* sh */,
+/* u h l */ HI(37) /* lhu */,
+/* u i s */ HI(43) /* sw */,
+/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
+
+/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
+/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
+/* s b s */ HI(40) /* sb */,
+/* s b l */ HI(32) /* lb */,
+/* s h s */ HI(41) /* sh */,
+/* s h l */ HI(33) /* lh */,
+/* s i s */ HI(43) /* sw */,
+/* s i l */ HI(35) /* lw */,
+
+/* d s */ HI(61) /* sdc1 */,
+/* d l */ HI(53) /* ldc1 */,
+/* s s */ HI(57) /* swc1 */,
+/* s l */ HI(49) /* lwc1 */,
+};
+
+#undef ARCH_32_64
+
+/* reg_ar is an absoulute register! */
+
+/* Can perform an operation using at most 1 instruction. */
+static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) && !(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ /* Works for both absoulte and relative addresses. */
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)
+ | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));
+ return -1;
+ }
+ return 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
+
+ /* Simple operation except for updates. */
+ if (arg & OFFS_REG_MASK) {
+ argw &= 0x3;
+ next_argw &= 0x3;
+ if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
+ return 1;
+ return 0;
+ }
+
+ if (arg == next_arg) {
+ if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))
+ return 1;
+ return 0;
+ }
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_s32 tmp_ar, base, delay_slot;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
+ tmp_ar = reg_ar;
+ delay_slot = reg_ar;
+ } else {
+ tmp_ar = DR(TMP_REG1);
+ delay_slot = MOVABLE_INS;
+ }
+ base = arg & REG_MASK;
+
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ argw &= 0x3;
+ if ((flags & WRITE_BACK) && reg_ar == DR(base)) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ reg_ar = DR(TMP_REG1);
+ }
+
+ /* Using the cache. */
+ if (argw == compiler->cache_argw) {
+ if (!(flags & WRITE_BACK)) {
+ if (arg == compiler->cache_arg)
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
+ if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
+ }
+ }
+ else {
+ if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
+ }
+ }
+ }
+
+ if (SLJIT_UNLIKELY(argw)) {
+ compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
+ }
+
+ if (!(flags & WRITE_BACK)) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
+ tmp_ar = DR(TMP_REG3);
+ }
+ else
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(base), DR(base)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
+ }
+
+ if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
+ /* Update only applies if a base register exists. */
+ if (reg_ar == DR(base)) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS));
+ if (argw)
+ return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base));
+ return SLJIT_SUCCESS;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ reg_ar = DR(TMP_REG1);
+ }
+
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (argw)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)));
+ }
+ else {
+ if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ compiler->cache_argw = argw;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ }
+ else {
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ }
+ }
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
+ }
+
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ compiler->cache_argw = argw;
+ }
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ }
+ else {
+ compiler->cache_arg = SLJIT_MEM;
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ }
+ compiler->cache_argw = argw;
+
+ if (!base)
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
+
+ if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
+ compiler->cache_arg = arg;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
+ }
+
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
+{
+ if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ return compiler->error;
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+}
+
+static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ sljit_s32 dst_r = TMP_REG2;
+ sljit_s32 src1_r;
+ sljit_sw src2_r = 0;
+ sljit_s32 sugg_src2_r = TMP_REG2;
+
+ if (!(flags & ALT_KEEP_CACHE)) {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ }
+
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ if (GET_FLAGS(op))
+ flags |= UNUSED_DEST;
+ }
+ else if (FAST_IS_REG(dst)) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ sugg_src2_r = dst_r;
+ }
+ else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (flags & IMM_OP) {
+ if ((src2 & SLJIT_IMM) && src2w) {
+ if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN))
+ || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src2w;
+ }
+ }
+ if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
+ if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN))
+ || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src1w;
+
+ /* And swap arguments. */
+ src1 = src2;
+ src1w = src2w;
+ src2 = SLJIT_IMM;
+ /* src2w = src2_r unneeded. */
+ }
+ }
+ }
+
+ /* Source 1. */
+ if (FAST_IS_REG(src1)) {
+ src1_r = src1;
+ flags |= REG1_SOURCE;
+ }
+ else if (src1 & SLJIT_IMM) {
+ if (src1w) {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
+ src1_r = TMP_REG1;
+ }
+ else
+ src1_r = 0;
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ src1_r = TMP_REG1;
+ }
+
+ /* Source 2. */
+ if (FAST_IS_REG(src2)) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ dst_r = src2_r;
+ }
+ else if (src2 & SLJIT_IMM) {
+ if (!(flags & SRC2_IMM)) {
+ if (src2w) {
+ FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));
+ src2_r = sugg_src2_r;
+ }
+ else {
+ src2_r = 0;
+ if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
+ dst_r = 0;
+ }
+ }
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ src2_r = sugg_src2_r;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ SLJIT_ASSERT(src2_r == TMP_REG2);
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ sljit_s32 int_op = op & SLJIT_I32_OP;
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ return push_inst(compiler, BREAK, UNMOVABLE_INS);
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
+#else
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
+#endif
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
+ return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+ SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
+#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ if (int_op)
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
+ else
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
+#else
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
+#endif
+
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
+ return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# define flags 0
+#else
+ sljit_s32 flags = 0;
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT) {
+ flags |= INT_DATA | SIGNED_DATA;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s32)srcw;
+ }
+#endif
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_U32:
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+ return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
+#endif
+
+ case SLJIT_MOV_S32:
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+ return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
+#endif
+
+ case SLJIT_MOV_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
+
+ case SLJIT_MOV_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
+
+ case SLJIT_MOV_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
+
+ case SLJIT_MOV_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
+
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_P:
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_U32:
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+ return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
+#endif
+
+ case SLJIT_MOVU_S32:
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+ return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
+#endif
+
+ case SLJIT_MOVU_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
+
+ case SLJIT_MOVU_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
+
+ case SLJIT_MOVU_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
+
+ case SLJIT_MOVU_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
+
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# undef flags
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# define flags 0
+#else
+ sljit_s32 flags = 0;
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ if (op & SLJIT_I32_OP) {
+ flags |= INT_DATA | SIGNED_DATA;
+ if (src1 & SLJIT_IMM)
+ src1w = (sljit_s32)src1w;
+ if (src2 & SLJIT_IMM)
+ src2w = (sljit_s32)src2w;
+ }
+#endif
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+ return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ if (src2 & SLJIT_IMM)
+ src2w &= 0x1f;
+#else
+ if (src2 & SLJIT_IMM) {
+ if (op & SLJIT_I32_OP)
+ src2w &= 0x1f;
+ else
+ src2w &= 0x3f;
+ }
+#endif
+ return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# undef flags
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ return reg << 1;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+#ifdef SLJIT_IS_FPU_AVAILABLE
+ return SLJIT_IS_FPU_AVAILABLE;
+#elif defined(__GNUC__)
+ sljit_sw fir;
+ asm ("cfc1 %0, $0" : "=r"(fir));
+ return (fir >> 22) & 0x1;
+#else
+#error "FIR check is not implemented for this architecture"
+#endif
+}
+
+#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
+#define FMT(op) (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) << (21 - 8))
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# define flags 0
+#else
+ sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) << 21;
+#endif
+
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+ src = TMP_FREG1;
+ }
+ else
+ src <<= 1;
+
+ FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS);
+
+ /* Store the integer value from a VFP register. */
+ return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# undef is_long
+#endif
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# define flags 0
+#else
+ sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21;
+#endif
+
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
+ else if (src & SLJIT_MEM) {
+ /* Load the integer value into a VFP register. */
+ FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
+ srcw = (sljit_s32)srcw;
+#endif
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
+ FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
+ }
+
+ FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# undef flags
+#endif
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+ src1 = TMP_FREG1;
+ }
+ else
+ src1 <<= 1;
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
+ src2 = TMP_FREG2;
+ }
+ else
+ src2 <<= 1;
+
+ /* src2 and src1 are swapped. */
+ if (op & SLJIT_SET_E) {
+ FAIL_IF(push_inst(compiler, C_UEQ_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG));
+ }
+ if (op & SLJIT_SET_S) {
+ /* Mixing the instructions for the two checks. */
+ FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src1) | FS(src2), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG));
+ }
+ return push_inst(compiler, C_UN_S | FMT(op) | FT(src2) | FS(src1), FCSR_FCC);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
+
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
+ op ^= SLJIT_F32_OP;
+
+ dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
+ src = dst_r;
+ }
+ else
+ src <<= 1;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_F64:
+ if (src != dst_r) {
+ if (dst_r != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
+ else
+ dst_r = src;
+ }
+ break;
+ case SLJIT_NEG_F64:
+ FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
+ break;
+ case SLJIT_ABS_F64:
+ FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
+ break;
+ case SLJIT_CONV_F64_FROM_F32:
+ FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_F32_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
+ op ^= SLJIT_F32_OP;
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r, flags = 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
+
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1 = TMP_FREG1;
+ } else
+ flags |= SLOW_SRC1;
+ }
+ else
+ src1 <<= 1;
+
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2 = TMP_FREG2;
+ } else
+ flags |= SLOW_SRC2;
+ }
+ else
+ src2 <<= 1;
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+
+ if (flags & SLOW_SRC1)
+ src1 = TMP_FREG1;
+ if (flags & SLOW_SRC2)
+ src2 = TMP_FREG2;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD_F64:
+ FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
+ break;
+
+ case SLJIT_SUB_F64:
+ FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
+ break;
+
+ case SLJIT_MUL_F64:
+ FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
+ break;
+
+ case SLJIT_DIV_F64:
+ FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
+ break;
+ }
+
+ if (dst_r == TMP_FREG2)
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst));
+
+ /* Memory. */
+ return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw));
+
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ compiler->delay_slot = UNMOVABLE_INS;
+ return label;
+}
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define JUMP_LENGTH 4
+#else
+#define JUMP_LENGTH 8
+#endif
+
+#define BR_Z(src) \
+ inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \
+ flags = IS_BIT26_COND; \
+ delay_check = src;
+
+#define BR_NZ(src) \
+ inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \
+ flags = IS_BIT26_COND; \
+ delay_check = src;
+
+#define BR_T() \
+ inst = BC1T | JUMP_LENGTH; \
+ flags = IS_BIT16_COND; \
+ delay_check = FCSR_FCC;
+
+#define BR_F() \
+ inst = BC1F | JUMP_LENGTH; \
+ flags = IS_BIT16_COND; \
+ delay_check = FCSR_FCC;
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ struct sljit_jump *jump;
+ sljit_ins inst;
+ sljit_s32 flags = 0;
+ sljit_s32 delay_check = UNMOVABLE_INS;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_NOT_EQUAL_F64:
+ BR_NZ(EQUAL_FLAG);
+ break;
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_EQUAL_F64:
+ BR_Z(EQUAL_FLAG);
+ break;
+ case SLJIT_LESS:
+ case SLJIT_LESS_F64:
+ BR_Z(ULESS_FLAG);
+ break;
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ BR_NZ(ULESS_FLAG);
+ break;
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_F64:
+ BR_Z(UGREATER_FLAG);
+ break;
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ BR_NZ(UGREATER_FLAG);
+ break;
+ case SLJIT_SIG_LESS:
+ BR_Z(LESS_FLAG);
+ break;
+ case SLJIT_SIG_GREATER_EQUAL:
+ BR_NZ(LESS_FLAG);
+ break;
+ case SLJIT_SIG_GREATER:
+ BR_Z(GREATER_FLAG);
+ break;
+ case SLJIT_SIG_LESS_EQUAL:
+ BR_NZ(GREATER_FLAG);
+ break;
+ case SLJIT_OVERFLOW:
+ case SLJIT_MUL_OVERFLOW:
+ BR_Z(OVERFLOW_FLAG);
+ break;
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ BR_NZ(OVERFLOW_FLAG);
+ break;
+ case SLJIT_UNORDERED_F64:
+ BR_F();
+ break;
+ case SLJIT_ORDERED_F64:
+ BR_T();
+ break;
+ default:
+ /* Not conditional branch. */
+ inst = 0;
+ break;
+ }
+
+ jump->flags |= flags;
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
+ jump->flags |= IS_MOVABLE;
+
+ if (inst)
+ PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ if (type <= SLJIT_JUMP) {
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ } else {
+ SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+ /* Cannot be optimized out if type is >= CALL0. */
+ jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? IS_CALL : 0);
+ PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ /* A NOP if type < CALL1. */
+ PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS));
+ }
+ return jump;
+}
+
+#define RESOLVE_IMM1() \
+ if (src1 & SLJIT_IMM) { \
+ if (src1w) { \
+ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
+ src1 = TMP_REG1; \
+ } \
+ else \
+ src1 = 0; \
+ }
+
+#define RESOLVE_IMM2() \
+ if (src2 & SLJIT_IMM) { \
+ if (src2w) { \
+ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
+ src2 = TMP_REG2; \
+ } \
+ else \
+ src2 = 0; \
+ }
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ struct sljit_jump *jump;
+ sljit_s32 flags;
+ sljit_ins inst;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ flags = ((type & SLJIT_I32_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA;
+ if (src1 & SLJIT_MEM) {
+ PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
+ src1 = TMP_REG1;
+ }
+ if (src2 & SLJIT_MEM) {
+ PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));
+ src2 = TMP_REG2;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type <= SLJIT_NOT_EQUAL) {
+ RESOLVE_IMM1();
+ RESOLVE_IMM2();
+ jump->flags |= IS_BIT26_COND;
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
+ jump->flags |= IS_MOVABLE;
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+ else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) {
+ inst = NOP;
+ if ((src1 & SLJIT_IMM) && (src1w == 0)) {
+ RESOLVE_IMM2();
+ switch (type) {
+ case SLJIT_SIG_LESS:
+ inst = BLEZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_SIG_GREATER_EQUAL:
+ inst = BGTZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_SIG_GREATER:
+ inst = BGEZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_SIG_LESS_EQUAL:
+ inst = BLTZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ }
+ src1 = src2;
+ }
+ else {
+ RESOLVE_IMM1();
+ switch (type) {
+ case SLJIT_SIG_LESS:
+ inst = BGEZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_SIG_GREATER_EQUAL:
+ inst = BLTZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_SIG_GREATER:
+ inst = BLEZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_SIG_LESS_EQUAL:
+ inst = BGTZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ }
+ }
+ PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+ else {
+ if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {
+ RESOLVE_IMM1();
+ if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
+ else {
+ RESOLVE_IMM2();
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
+ }
+ type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
+ }
+ else {
+ RESOLVE_IMM2();
+ if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
+ else {
+ RESOLVE_IMM1();
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
+ }
+ type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
+ }
+
+ jump->flags |= IS_BIT26_COND;
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return jump;
+}
+
+#undef RESOLVE_IMM1
+#undef RESOLVE_IMM2
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ struct sljit_jump *jump;
+ sljit_ins inst;
+ sljit_s32 if_true;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (src1 & SLJIT_MEM) {
+ PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+ src1 = TMP_FREG1;
+ }
+ else
+ src1 <<= 1;
+
+ if (src2 & SLJIT_MEM) {
+ PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
+ src2 = TMP_FREG2;
+ }
+ else
+ src2 <<= 1;
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ jump->flags |= IS_BIT16_COND;
+
+ switch (type & 0xff) {
+ case SLJIT_EQUAL_F64:
+ inst = C_UEQ_S;
+ if_true = 1;
+ break;
+ case SLJIT_NOT_EQUAL_F64:
+ inst = C_UEQ_S;
+ if_true = 0;
+ break;
+ case SLJIT_LESS_F64:
+ inst = C_ULT_S;
+ if_true = 1;
+ break;
+ case SLJIT_GREATER_EQUAL_F64:
+ inst = C_ULT_S;
+ if_true = 0;
+ break;
+ case SLJIT_GREATER_F64:
+ inst = C_ULE_S;
+ if_true = 0;
+ break;
+ case SLJIT_LESS_EQUAL_F64:
+ inst = C_ULE_S;
+ if_true = 1;
+ break;
+ case SLJIT_UNORDERED_F64:
+ inst = C_UN_S;
+ if_true = 1;
+ break;
+ default: /* Make compilers happy. */
+ SLJIT_ASSERT_STOP();
+ case SLJIT_ORDERED_F64:
+ inst = C_UN_S;
+ if_true = 0;
+ break;
+ }
+
+ PTR_FAIL_IF(push_inst(compiler, inst | FMT(type) | FT(src2) | FS(src1), UNMOVABLE_INS));
+ /* Intentionally the other opcode. */
+ PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS));
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return jump;
+}
+
+#undef JUMP_LENGTH
+#undef BR_Z
+#undef BR_NZ
+#undef BR_T
+#undef BR_F
+
+#undef FLOAT_DATA
+#undef FMT
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 src_r = TMP_REG2;
+ struct sljit_jump *jump = NULL;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src)) {
+ if (DR(src) != 4)
+ src_r = src;
+ else
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ }
+
+ if (type >= SLJIT_CALL0) {
+ SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+ if (src & (SLJIT_IMM | SLJIT_MEM)) {
+ if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
+ else {
+ SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ }
+ FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ /* We need an extra instruction in any case. */
+ return push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS);
+ }
+
+ /* Register input. */
+ if (type >= SLJIT_CALL1)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), 4));
+ FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS);
+ }
+
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
+ jump->u.target = srcw;
+
+ if (compiler->delay_slot != UNMOVABLE_INS)
+ jump->flags |= IS_MOVABLE;
+
+ FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ }
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+
+ FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS));
+ if (jump)
+ jump->addr = compiler->size;
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ sljit_s32 sugg_dst_ar, dst_ar;
+ sljit_s32 flags = GET_ALL_FLAGS(op);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# define mem_type WORD_DATA
+#else
+ sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ op = GET_OPCODE(op);
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32)
+ mem_type = INT_DATA | SIGNED_DATA;
+#endif
+ sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
+ ADJUST_LOCAL_OFFSET(src, srcw);
+ FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw));
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ switch (type & 0xff) {
+ case SLJIT_EQUAL:
+ case SLJIT_NOT_EQUAL:
+ FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ break;
+ case SLJIT_LESS:
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_LESS_F64:
+ case SLJIT_GREATER_EQUAL_F64:
+ dst_ar = ULESS_FLAG;
+ break;
+ case SLJIT_GREATER:
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_GREATER_F64:
+ case SLJIT_LESS_EQUAL_F64:
+ dst_ar = UGREATER_FLAG;
+ break;
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_GREATER_EQUAL:
+ dst_ar = LESS_FLAG;
+ break;
+ case SLJIT_SIG_GREATER:
+ case SLJIT_SIG_LESS_EQUAL:
+ dst_ar = GREATER_FLAG;
+ break;
+ case SLJIT_OVERFLOW:
+ case SLJIT_NOT_OVERFLOW:
+ dst_ar = OVERFLOW_FLAG;
+ break;
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ type ^= 0x1; /* Flip type bit for the XORI below. */
+ break;
+ case SLJIT_EQUAL_F64:
+ case SLJIT_NOT_EQUAL_F64:
+ dst_ar = EQUAL_FLAG;
+ break;
+
+ case SLJIT_UNORDERED_F64:
+ case SLJIT_ORDERED_F64:
+ FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar));
+ FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar));
+ FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ dst_ar = sugg_dst_ar;
+ break;
+ }
+
+ if (type & 0x1) {
+ FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ }
+
+ if (op >= SLJIT_ADD) {
+ if (DR(TMP_REG2) != dst_ar)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);
+
+ if (sugg_dst_ar != dst_ar)
+ return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar);
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+# undef mem_type
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_const *const_;
+ sljit_s32 reg;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ return const_;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
new file mode 100644
index 0000000000..f696d1b8d5
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
@@ -0,0 +1,271 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ppc 32-bit arch dependent functions. */
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
+{
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
+
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
+
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
+}
+
+#define INS_CLEAR_LEFT(dst, src, from) \
+ (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))
+
+static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
+{
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ case SLJIT_MOV_P:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S8)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
+ }
+ else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ else {
+ SLJIT_ASSERT(dst == src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S16)
+ return push_inst(compiler, EXTSH | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
+ }
+ else {
+ SLJIT_ASSERT(dst == src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
+
+ case SLJIT_NEG:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
+
+ case SLJIT_ADD:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM4) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+ return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
+ return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_ADDC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | D(0)));
+ FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_SUB:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & (ALT_FORM2 | ALT_FORM3)) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2)
+ FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));
+ if (flags & ALT_FORM3)
+ return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm);
+ return SLJIT_SUCCESS;
+ }
+ if (flags & (ALT_FORM4 | ALT_FORM5)) {
+ if (flags & ALT_FORM4)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
+ if (flags & ALT_FORM5)
+ FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));
+ return SLJIT_SUCCESS;
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+ if (flags & ALT_FORM6)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
+ return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_SUBC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | D(0)));
+ FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_MUL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
+ }
+ return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_AND:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
+ }
+ return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_OR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_XOR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_SHL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
+ }
+ return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_LSHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
+ }
+ return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_ASHR:
+ if (flags & ALT_FORM3)
+ FAIL_IF(push_inst(compiler, MFXER | D(0)));
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
+ }
+ else
+ FAIL_IF(push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)));
+ return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
+{
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
new file mode 100644
index 0000000000..386d247dbc
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
@@ -0,0 +1,423 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ppc 64-bit arch dependent functions. */
+
+#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
+#define ASM_SLJIT_CLZ(src, dst) \
+ __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
+#elif defined(__xlc__)
+#error "Please enable GCC syntax for inline assembly statements"
+#else
+#error "Must implement count leading zeroes"
+#endif
+
+#define RLDI(dst, src, sh, mb, type) \
+ (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
+
+#define PUSH_RLDICR(reg, shift) \
+ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
+{
+ sljit_uw tmp;
+ sljit_uw shift;
+ sljit_uw tmp2;
+ sljit_uw shift2;
+
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
+
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
+
+ if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
+ }
+
+ /* Count leading zeroes. */
+ tmp = (imm >= 0) ? imm : ~imm;
+ ASM_SLJIT_CLZ(tmp, shift);
+ SLJIT_ASSERT(shift > 0);
+ shift--;
+ tmp = (imm << shift);
+
+ if ((tmp & ~0xffff000000000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ shift += 15;
+ return PUSH_RLDICR(reg, shift);
+ }
+
+ if ((tmp & ~0xffffffff00000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));
+ shift += 31;
+ return PUSH_RLDICR(reg, shift);
+ }
+
+ /* Cut out the 16 bit from immediate. */
+ shift += 15;
+ tmp2 = imm & ((1ul << (63 - shift)) - 1);
+
+ if (tmp2 <= 0xffff) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2);
+ }
+
+ if (tmp2 <= 0xffffffff) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;
+ }
+
+ ASM_SLJIT_CLZ(tmp2, shift2);
+ tmp2 <<= shift2;
+
+ if ((tmp2 & ~0xffff000000000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ shift2 += 15;
+ shift += (63 - shift2);
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48)));
+ return PUSH_RLDICR(reg, shift2);
+ }
+
+ /* The general version. */
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));
+ FAIL_IF(PUSH_RLDICR(reg, 31));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));
+}
+
+/* Simplified mnemonics: clrldi. */
+#define INS_CLEAR_LEFT(dst, src, from) \
+ (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5))
+
+/* Sign extension for integer operations. */
+#define UN_EXTS() \
+ if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
+ src2 = TMP_REG2; \
+ }
+
+#define BIN_EXTS() \
+ if (flags & ALT_SIGN_EXT) { \
+ if (flags & REG1_SOURCE) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
+ src1 = TMP_REG1; \
+ } \
+ if (flags & REG2_SOURCE) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
+ src2 = TMP_REG2; \
+ } \
+ }
+
+#define BIN_IMM_EXTS() \
+ if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
+ src1 = TMP_REG1; \
+ }
+
+static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
+{
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S32)
+ return push_inst(compiler, EXTSW | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
+ }
+ else {
+ SLJIT_ASSERT(dst == src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S8)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
+ }
+ else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ else {
+ SLJIT_ASSERT(dst == src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S16)
+ return push_inst(compiler, EXTSH | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
+ }
+ else {
+ SLJIT_ASSERT(dst == src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ UN_EXTS();
+ return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
+
+ case SLJIT_NEG:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ UN_EXTS();
+ return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (flags & ALT_FORM1)
+ return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
+ return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst));
+
+ case SLJIT_ADD:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ BIN_IMM_EXTS();
+ return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM4) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+ return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
+ BIN_EXTS();
+ return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_ADDC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | D(0)));
+ FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ BIN_EXTS();
+ return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_SUB:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & (ALT_FORM2 | ALT_FORM3)) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2)
+ FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
+ if (flags & ALT_FORM3)
+ return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
+ return SLJIT_SUCCESS;
+ }
+ if (flags & (ALT_FORM4 | ALT_FORM5)) {
+ if (flags & ALT_FORM4)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+ if (flags & ALT_FORM5)
+ return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
+ return SLJIT_SUCCESS;
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+ BIN_EXTS();
+ if (flags & ALT_FORM6)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+ return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_SUBC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | D(0)));
+ FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ BIN_EXTS();
+ return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_MUL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
+ }
+ BIN_EXTS();
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
+ return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_AND:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
+ }
+ return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_OR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_XOR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_SHL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
+ }
+ }
+ return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_LSHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
+ }
+ }
+ return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_ASHR:
+ if (flags & ALT_FORM3)
+ FAIL_IF(push_inst(compiler, MFXER | D(0)));
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4)));
+ }
+ }
+ else
+ FAIL_IF(push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2)));
+ return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
+{
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
+ FAIL_IF(PUSH_RLDICR(reg, 31));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+ inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 5);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 5);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
new file mode 100644
index 0000000000..150c0bf9f4
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
@@ -0,0 +1,2393 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "PowerPC" SLJIT_CPUINFO;
+}
+
+/* Length of an instruction word.
+ Both for ppc-32 and ppc-64. */
+typedef sljit_u32 sljit_ins;
+
+#if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_PPC_STACK_FRAME_V2 1
+#endif
+
+#ifdef _AIX
+#include <sys/cache.h>
+#endif
+
+#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1
+#endif
+
+#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
+
+static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
+{
+#ifdef _AIX
+ _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));
+#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
+# if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
+ /* Cache flush for POWER architecture. */
+ while (from < to) {
+ __asm__ volatile (
+ "clf 0, %0\n"
+ "dcs\n"
+ : : "r"(from)
+ );
+ from++;
+ }
+ __asm__ volatile ( "ics" );
+# elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
+# error "Cache flush is not implemented for PowerPC/POWER common mode."
+# else
+ /* Cache flush for PowerPC architecture. */
+ while (from < to) {
+ __asm__ volatile (
+ "dcbf 0, %0\n"
+ "sync\n"
+ "icbi 0, %0\n"
+ : : "r"(from)
+ );
+ from++;
+ }
+ __asm__ volatile ( "isync" );
+# endif
+# ifdef __xlc__
+# warning "This file may fail to compile if -qfuncsect is used"
+# endif
+#elif defined(__xlc__)
+#error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
+#else
+#error "This platform requires a cache flush implementation."
+#endif /* _AIX */
+}
+
+#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
+
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+#define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 5)
+
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
+#define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 6)
+#else
+#define TMP_CALL_REG TMP_REG2
+#endif
+
+#define TMP_FREG1 (0)
+#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
+ 0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12
+};
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+#define D(d) (reg_map[d] << 21)
+#define S(s) (reg_map[s] << 21)
+#define A(a) (reg_map[a] << 16)
+#define B(b) (reg_map[b] << 11)
+#define C(c) (reg_map[c] << 6)
+#define FD(fd) ((fd) << 21)
+#define FS(fs) ((fs) << 21)
+#define FA(fa) ((fa) << 16)
+#define FB(fb) ((fb) << 11)
+#define FC(fc) ((fc) << 6)
+#define IMM(imm) ((imm) & 0xffff)
+#define CRD(d) ((d) << 21)
+
+/* Instruction bit sections.
+ OE and Rc flag (see ALT_SET_FLAGS). */
+#define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
+/* Rc flag (see ALT_SET_FLAGS). */
+#define RC(flags) ((flags & ALT_SET_FLAGS) >> 10)
+#define HI(opcode) ((opcode) << 26)
+#define LO(opcode) ((opcode) << 1)
+
+#define ADD (HI(31) | LO(266))
+#define ADDC (HI(31) | LO(10))
+#define ADDE (HI(31) | LO(138))
+#define ADDI (HI(14))
+#define ADDIC (HI(13))
+#define ADDIS (HI(15))
+#define ADDME (HI(31) | LO(234))
+#define AND (HI(31) | LO(28))
+#define ANDI (HI(28))
+#define ANDIS (HI(29))
+#define Bx (HI(18))
+#define BCx (HI(16))
+#define BCCTR (HI(19) | LO(528) | (3 << 11))
+#define BLR (HI(19) | LO(16) | (0x14 << 21))
+#define CNTLZD (HI(31) | LO(58))
+#define CNTLZW (HI(31) | LO(26))
+#define CMP (HI(31) | LO(0))
+#define CMPI (HI(11))
+#define CMPL (HI(31) | LO(32))
+#define CMPLI (HI(10))
+#define CROR (HI(19) | LO(449))
+#define DIVD (HI(31) | LO(489))
+#define DIVDU (HI(31) | LO(457))
+#define DIVW (HI(31) | LO(491))
+#define DIVWU (HI(31) | LO(459))
+#define EXTSB (HI(31) | LO(954))
+#define EXTSH (HI(31) | LO(922))
+#define EXTSW (HI(31) | LO(986))
+#define FABS (HI(63) | LO(264))
+#define FADD (HI(63) | LO(21))
+#define FADDS (HI(59) | LO(21))
+#define FCFID (HI(63) | LO(846))
+#define FCMPU (HI(63) | LO(0))
+#define FCTIDZ (HI(63) | LO(815))
+#define FCTIWZ (HI(63) | LO(15))
+#define FDIV (HI(63) | LO(18))
+#define FDIVS (HI(59) | LO(18))
+#define FMR (HI(63) | LO(72))
+#define FMUL (HI(63) | LO(25))
+#define FMULS (HI(59) | LO(25))
+#define FNEG (HI(63) | LO(40))
+#define FRSP (HI(63) | LO(12))
+#define FSUB (HI(63) | LO(20))
+#define FSUBS (HI(59) | LO(20))
+#define LD (HI(58) | 0)
+#define LWZ (HI(32))
+#define MFCR (HI(31) | LO(19))
+#define MFLR (HI(31) | LO(339) | 0x80000)
+#define MFXER (HI(31) | LO(339) | 0x10000)
+#define MTCTR (HI(31) | LO(467) | 0x90000)
+#define MTLR (HI(31) | LO(467) | 0x80000)
+#define MTXER (HI(31) | LO(467) | 0x10000)
+#define MULHD (HI(31) | LO(73))
+#define MULHDU (HI(31) | LO(9))
+#define MULHW (HI(31) | LO(75))
+#define MULHWU (HI(31) | LO(11))
+#define MULLD (HI(31) | LO(233))
+#define MULLI (HI(7))
+#define MULLW (HI(31) | LO(235))
+#define NEG (HI(31) | LO(104))
+#define NOP (HI(24))
+#define NOR (HI(31) | LO(124))
+#define OR (HI(31) | LO(444))
+#define ORI (HI(24))
+#define ORIS (HI(25))
+#define RLDICL (HI(30))
+#define RLWINM (HI(21))
+#define SLD (HI(31) | LO(27))
+#define SLW (HI(31) | LO(24))
+#define SRAD (HI(31) | LO(794))
+#define SRADI (HI(31) | LO(413 << 1))
+#define SRAW (HI(31) | LO(792))
+#define SRAWI (HI(31) | LO(824))
+#define SRD (HI(31) | LO(539))
+#define SRW (HI(31) | LO(536))
+#define STD (HI(62) | 0)
+#define STDU (HI(62) | 1)
+#define STDUX (HI(31) | LO(181))
+#define STFIWX (HI(31) | LO(983))
+#define STW (HI(36))
+#define STWU (HI(37))
+#define STWUX (HI(31) | LO(183))
+#define SUBF (HI(31) | LO(40))
+#define SUBFC (HI(31) | LO(8))
+#define SUBFE (HI(31) | LO(136))
+#define SUBFIC (HI(8))
+#define XOR (HI(31) | LO(316))
+#define XORI (HI(26))
+#define XORIS (HI(27))
+
+#define SIMM_MAX (0x7fff)
+#define SIMM_MIN (-0x8000)
+#define UIMM_MAX (0xffff)
+
+#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)
+{
+ sljit_sw* ptrs;
+ if (func_ptr)
+ *func_ptr = (void*)context;
+ ptrs = (sljit_sw*)func;
+ context->addr = addr ? addr : ptrs[0];
+ context->r2 = ptrs[1];
+ context->r11 = ptrs[2];
+}
+#endif
+
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
+{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+{
+ sljit_sw diff;
+ sljit_uw target_addr;
+ sljit_sw extra_jump_flags;
+
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
+ return 0;
+#else
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+#endif
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
+ }
+
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (jump->flags & IS_CALL)
+ goto keep_address;
+#endif
+
+ diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;
+
+ extra_jump_flags = 0;
+ if (jump->flags & IS_COND) {
+ if (diff <= 0x7fff && diff >= -0x8000) {
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ if (target_addr <= 0xffff) {
+ jump->flags |= PATCH_B | PATCH_ABS_B;
+ return 1;
+ }
+ extra_jump_flags = REMOVE_COND;
+
+ diff -= sizeof(sljit_ins);
+ }
+
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ jump->flags |= PATCH_B | extra_jump_flags;
+ return 1;
+ }
+
+ if (target_addr <= 0x03ffffff) {
+ jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
+ return 1;
+ }
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
+keep_address:
+#endif
+ if (target_addr <= 0x7fffffff) {
+ jump->flags |= PATCH_ABS32;
+ return 1;
+ }
+
+ if (target_addr <= 0x7fffffffffffl) {
+ jump->flags |= PATCH_ABS48;
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_sw executable_offset;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
+#else
+ compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
+#endif
+#endif
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ jump->addr = (sljit_uw)(code_ptr - 3);
+#else
+ jump->addr = (sljit_uw)(code_ptr - 6);
+#endif
+ if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ code_ptr[-3] = code_ptr[0];
+ code_ptr -= 3;
+#else
+ if (jump->flags & PATCH_ABS32) {
+ code_ptr -= 3;
+ code_ptr[-1] = code_ptr[2];
+ code_ptr[0] = code_ptr[3];
+ }
+ else if (jump->flags & PATCH_ABS48) {
+ code_ptr--;
+ code_ptr[-1] = code_ptr[0];
+ code_ptr[0] = code_ptr[1];
+ /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
+ SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
+ code_ptr[-3] ^= 0x8422;
+ /* oris -> ori */
+ code_ptr[-2] ^= 0x4000000;
+ }
+ else {
+ code_ptr[-6] = code_ptr[0];
+ code_ptr -= 6;
+ }
+#endif
+ if (jump->flags & REMOVE_COND) {
+ code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
+ code_ptr++;
+ jump->addr += sizeof(sljit_ins);
+ code_ptr[0] = Bx;
+ jump->flags -= IS_COND;
+ }
+ }
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));
+#else
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
+#endif
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins *)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ if (jump->flags & IS_COND) {
+ if (!(jump->flags & PATCH_ABS_B)) {
+ addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
+ SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
+ *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
+ }
+ else {
+ SLJIT_ASSERT(addr <= 0xffff);
+ *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
+ }
+ }
+ else {
+ if (!(jump->flags & PATCH_ABS_B)) {
+ addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
+ SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
+ *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
+ }
+ else {
+ SLJIT_ASSERT(addr <= 0x03ffffff);
+ *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
+ }
+ }
+ break;
+ }
+
+ /* Set the fields of immediate loads. */
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+#else
+ if (jump->flags & PATCH_ABS32) {
+ SLJIT_ASSERT(addr <= 0x7fffffff);
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+ break;
+ }
+ if (jump->flags & PATCH_ABS48) {
+ SLJIT_ASSERT(addr <= 0x7fffffffffff);
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);
+ break;
+ }
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
+#endif
+ } while (0);
+ jump = jump->next;
+ }
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+
+ code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+
+#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (((sljit_sw)code_ptr) & 0x4)
+ code_ptr++;
+#endif
+ sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
+#endif
+
+ code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+
+#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+ return code_ptr;
+#else
+ return code;
+#endif
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+/* inp_flags: */
+
+/* Creates an index in data_transfer_insts array. */
+#define LOAD_DATA 0x01
+#define INDEXED 0x02
+#define WRITE_BACK 0x04
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x08
+#define HALF_DATA 0x10
+#define INT_DATA 0x18
+#define SIGNED_DATA 0x20
+/* Separates integer and floating point registers */
+#define GPR_REG 0x3f
+#define DOUBLE_DATA 0x40
+
+#define MEM_MASK 0x7f
+
+/* Other inp_flags. */
+
+#define ARG_TEST 0x000100
+/* Integer opertion and set flags -> requires exts on 64 bit systems. */
+#define ALT_SIGN_EXT 0x000200
+/* This flag affects the RC() and OERC() macros. */
+#define ALT_SET_FLAGS 0x000400
+#define ALT_KEEP_CACHE 0x000800
+#define ALT_FORM1 0x010000
+#define ALT_FORM2 0x020000
+#define ALT_FORM3 0x040000
+#define ALT_FORM4 0x080000
+#define ALT_FORM5 0x100000
+#define ALT_FORM6 0x200000
+
+/* Source and destination is register. */
+#define REG_DEST 0x000001
+#define REG1_SOURCE 0x000002
+#define REG2_SOURCE 0x000004
+/* getput_arg_fast returned true. */
+#define FAST_DEST 0x000008
+/* Multiple instructions are required. */
+#define SLOW_DEST 0x000010
+/*
+ALT_SIGN_EXT 0x000200
+ALT_SET_FLAGS 0x000400
+ALT_FORM1 0x010000
+...
+ALT_FORM6 0x200000 */
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#include "sljitNativePPC_32.c"
+#else
+#include "sljitNativePPC_64.c"
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#define STACK_STORE STW
+#define STACK_LOAD LWZ
+#else
+#define STACK_STORE STD
+#define STACK_LOAD LD
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 i, tmp, offs;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ FAIL_IF(push_inst(compiler, MFLR | D(0)));
+ offs = -(sljit_s32)(sizeof(sljit_sw));
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
+
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--) {
+ offs -= (sljit_s32)(sizeof(sljit_sw));
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
+ }
+
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
+ offs -= (sljit_s32)(sizeof(sljit_sw));
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
+ }
+
+ SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));
+
+#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
+#else
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
+#endif
+
+ FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));
+
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
+ local_size = (local_size + 15) & ~0xf;
+ compiler->local_size = local_size;
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, -local_size));
+ FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
+ }
+#else
+ if (local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, -local_size));
+ FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
+ }
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
+ compiler->local_size = (local_size + 15) & ~0xf;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 i, tmp, offs;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
+ FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));
+ }
+
+#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
+#else
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
+#endif
+
+ offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
+
+ tmp = compiler->scratches;
+ for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
+ offs += (sljit_s32)(sizeof(sljit_sw));
+ }
+
+ tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = tmp; i <= SLJIT_S0; i++) {
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
+ offs += (sljit_s32)(sizeof(sljit_sw));
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
+ SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));
+
+ FAIL_IF(push_inst(compiler, MTLR | S(0)));
+ FAIL_IF(push_inst(compiler, BLR));
+
+ return SLJIT_SUCCESS;
+}
+
+#undef STACK_STORE
+#undef STACK_LOAD
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* i/x - immediate/indexed form
+ n/w - no write-back / write-back (1 bit)
+ s/l - store/load (1 bit)
+ u/s - signed/unsigned (1 bit)
+ w/b/h/i - word/byte/half/int allowed (2 bit)
+ It contans 32 items, but not all are different. */
+
+/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
+#define INT_ALIGNED 0x10000
+/* 64-bit only: there is no lwau instruction. */
+#define UPDATE_REQ 0x20000
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#define ARCH_32_64(a, b) a
+#define INST_CODE_AND_DST(inst, flags, reg) \
+ ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
+#else
+#define ARCH_32_64(a, b) b
+#define INST_CODE_AND_DST(inst, flags, reg) \
+ (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
+#endif
+
+static const sljit_ins data_transfer_insts[64 + 8] = {
+
+/* -------- Unsigned -------- */
+
+/* Word. */
+
+/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
+/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
+/* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+
+/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
+/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
+/* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+
+/* Byte. */
+
+/* u b n i s */ HI(38) /* stb */,
+/* u b n i l */ HI(34) /* lbz */,
+/* u b n x s */ HI(31) | LO(215) /* stbx */,
+/* u b n x l */ HI(31) | LO(87) /* lbzx */,
+
+/* u b w i s */ HI(39) /* stbu */,
+/* u b w i l */ HI(35) /* lbzu */,
+/* u b w x s */ HI(31) | LO(247) /* stbux */,
+/* u b w x l */ HI(31) | LO(119) /* lbzux */,
+
+/* Half. */
+
+/* u h n i s */ HI(44) /* sth */,
+/* u h n i l */ HI(40) /* lhz */,
+/* u h n x s */ HI(31) | LO(407) /* sthx */,
+/* u h n x l */ HI(31) | LO(279) /* lhzx */,
+
+/* u h w i s */ HI(45) /* sthu */,
+/* u h w i l */ HI(41) /* lhzu */,
+/* u h w x s */ HI(31) | LO(439) /* sthux */,
+/* u h w x l */ HI(31) | LO(311) /* lhzux */,
+
+/* Int. */
+
+/* u i n i s */ HI(36) /* stw */,
+/* u i n i l */ HI(32) /* lwz */,
+/* u i n x s */ HI(31) | LO(151) /* stwx */,
+/* u i n x l */ HI(31) | LO(23) /* lwzx */,
+
+/* u i w i s */ HI(37) /* stwu */,
+/* u i w i l */ HI(33) /* lwzu */,
+/* u i w x s */ HI(31) | LO(183) /* stwux */,
+/* u i w x l */ HI(31) | LO(55) /* lwzux */,
+
+/* -------- Signed -------- */
+
+/* Word. */
+
+/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
+/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
+/* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+
+/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
+/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
+/* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+
+/* Byte. */
+
+/* s b n i s */ HI(38) /* stb */,
+/* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */,
+/* s b n x s */ HI(31) | LO(215) /* stbx */,
+/* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
+
+/* s b w i s */ HI(39) /* stbu */,
+/* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */,
+/* s b w x s */ HI(31) | LO(247) /* stbux */,
+/* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
+
+/* Half. */
+
+/* s h n i s */ HI(44) /* sth */,
+/* s h n i l */ HI(42) /* lha */,
+/* s h n x s */ HI(31) | LO(407) /* sthx */,
+/* s h n x l */ HI(31) | LO(343) /* lhax */,
+
+/* s h w i s */ HI(45) /* sthu */,
+/* s h w i l */ HI(43) /* lhau */,
+/* s h w x s */ HI(31) | LO(439) /* sthux */,
+/* s h w x l */ HI(31) | LO(375) /* lhaux */,
+
+/* Int. */
+
+/* s i n i s */ HI(36) /* stw */,
+/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
+/* s i n x s */ HI(31) | LO(151) /* stwx */,
+/* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
+
+/* s i w i s */ HI(37) /* stwu */,
+/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */),
+/* s i w x s */ HI(31) | LO(183) /* stwux */,
+/* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
+
+/* -------- Double -------- */
+
+/* d n i s */ HI(54) /* stfd */,
+/* d n i l */ HI(50) /* lfd */,
+/* d n x s */ HI(31) | LO(727) /* stfdx */,
+/* d n x l */ HI(31) | LO(599) /* lfdx */,
+
+/* s n i s */ HI(52) /* stfs */,
+/* s n i l */ HI(48) /* lfs */,
+/* s n x s */ HI(31) | LO(663) /* stfsx */,
+/* s n x l */ HI(31) | LO(535) /* lfsx */,
+
+};
+
+#undef ARCH_32_64
+
+/* Simple cases, (no caching is required). */
+static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ sljit_ins inst;
+
+ /* Should work when (arg & REG_MASK) == 0. */
+ SLJIT_COMPILE_ASSERT(A(0) == 0, a0_must_be_0);
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (arg & OFFS_REG_MASK) {
+ if (argw & 0x3)
+ return 0;
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
+ FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg))));
+ return -1;
+ }
+
+ if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
+ inp_flags &= ~WRITE_BACK;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+ SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
+
+ if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ))
+ return 0;
+ if (inp_flags & ARG_TEST)
+ return 1;
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (argw > SIMM_MAX || argw < SIMM_MIN)
+ return 0;
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
+#endif
+
+ FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw)));
+ return -1;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those operator always
+ uses word arguments without write back. */
+static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_sw high_short, next_high_short;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ sljit_sw diff;
+#endif
+
+ SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
+
+ if (arg & OFFS_REG_MASK)
+ return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3));
+
+ if (next_arg & OFFS_REG_MASK)
+ return 0;
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
+ next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
+ return high_short == next_high_short;
+#else
+ if (argw <= 0x7fffffffl && argw >= -0x80000000l) {
+ high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
+ next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
+ if (high_short == next_high_short)
+ return 1;
+ }
+
+ diff = argw - next_argw;
+ if (!(arg & REG_MASK))
+ return diff <= SIMM_MAX && diff >= SIMM_MIN;
+
+ if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN)
+ return 1;
+
+ return 0;
+#endif
+}
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define ADJUST_CACHED_IMM(imm) \
+ if ((inst & INT_ALIGNED) && (imm & 0x3)) { \
+ /* Adjust cached value. Fortunately this is really a rare case */ \
+ compiler->cache_argw += imm & 0x3; \
+ FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
+ imm &= ~0x3; \
+ }
+#endif
+
+/* Emit the necessary instructions. See can_cache above. */
+static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_s32 tmp_r;
+ sljit_ins inst;
+ sljit_sw high_short, next_high_short;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ sljit_sw diff;
+#endif
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1;
+ /* Special case for "mov reg, [reg, ... ]". */
+ if ((arg & REG_MASK) == tmp_r)
+ tmp_r = TMP_REG1;
+
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ argw &= 0x3;
+ /* Otherwise getput_arg_fast would capture it. */
+ SLJIT_ASSERT(argw);
+
+ if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw)
+ tmp_r = TMP_REG3;
+ else {
+ if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1)));
+#else
+ FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1)));
+#endif
+ }
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
+ }
+
+ if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
+ inp_flags &= ~WRITE_BACK;
+
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+ SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (argw <= 0x7fff7fffl && argw >= -0x80000000l
+ && (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) {
+#endif
+
+ arg &= REG_MASK;
+ high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff;
+ /* The getput_arg_fast should handle this otherwise. */
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l);
+#else
+ SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ)));
+#endif
+
+ if (inp_flags & WRITE_BACK) {
+ if (arg == reg) {
+ FAIL_IF(push_inst(compiler, OR | S(reg) | A(tmp_r) | B(reg)));
+ reg = tmp_r;
+ }
+ tmp_r = arg;
+ FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16)));
+ }
+ else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) {
+ if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) {
+ next_high_short = (sljit_s32)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
+ if (high_short == next_high_short) {
+ compiler->cache_arg = SLJIT_MEM | arg;
+ compiler->cache_argw = high_short;
+ tmp_r = TMP_REG3;
+ }
+ }
+ FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16)));
+ }
+ else
+ tmp_r = TMP_REG3;
+
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw));
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ }
+
+ /* Everything else is PPC-64 only. */
+ if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
+ diff = argw - compiler->cache_argw;
+ if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ ADJUST_CACHED_IMM(diff);
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
+ }
+
+ diff = argw - next_argw;
+ if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r));
+ }
+
+ diff = argw - compiler->cache_argw;
+ if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ));
+ ADJUST_CACHED_IMM(diff);
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
+ }
+
+ if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
+ if (compiler->cache_argw != argw) {
+ FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff)));
+ compiler->cache_argw = argw;
+ }
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
+ }
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
+ }
+
+ diff = argw - next_argw;
+ if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK)));
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3));
+ }
+
+ if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+ else
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+
+ /* Get the indexed version instead of the normal one. */
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
+ return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
+#endif
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ return compiler->error;
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+}
+
+static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ sljit_s32 dst_r;
+ sljit_s32 src1_r;
+ sljit_s32 src2_r;
+ sljit_s32 sugg_src2_r = TMP_REG2;
+ sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS);
+
+ if (!(input_flags & ALT_KEEP_CACHE)) {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ }
+
+ /* Destination check. */
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ dst_r = TMP_REG2;
+ }
+ else if (FAST_IS_REG(dst)) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ sugg_src2_r = dst_r;
+ }
+ else {
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
+ flags |= FAST_DEST;
+ dst_r = TMP_REG2;
+ }
+ else {
+ flags |= SLOW_DEST;
+ dst_r = 0;
+ }
+ }
+
+ /* Source 1. */
+ if (FAST_IS_REG(src1)) {
+ src1_r = src1;
+ flags |= REG1_SOURCE;
+ }
+ else if (src1 & SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+ src1_r = TMP_REG1;
+ }
+ else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1_r = TMP_REG1;
+ }
+ else
+ src1_r = 0;
+
+ /* Source 2. */
+ if (FAST_IS_REG(src2)) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ dst_r = src2_r;
+ }
+ else if (src2 & SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
+ src2_r = sugg_src2_r;
+ }
+ else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2_r = sugg_src2_r;
+ }
+ else
+ src2_r = 0;
+
+ /* src1_r, src2_r and dst_r can be zero (=unprocessed).
+ All arguments are complex addressing modes, and it is a binary operator. */
+ if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ src1_r = TMP_REG1;
+ src2_r = TMP_REG2;
+ }
+ else if (src1_r == 0 && src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ src1_r = TMP_REG1;
+ }
+ else if (src1_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1_r = TMP_REG1;
+ }
+ else if (src2_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+ src2_r = sugg_src2_r;
+ }
+
+ if (dst_r == 0)
+ dst_r = TMP_REG2;
+
+ if (src1_r == 0) {
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
+ src1_r = TMP_REG1;
+ }
+
+ if (src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
+ src2_r = sugg_src2_r;
+ }
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (flags & (FAST_DEST | SLOW_DEST)) {
+ if (flags & FAST_DEST)
+ FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw));
+ else
+ FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ sljit_s32 int_op = op & SLJIT_I32_OP;
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP);
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
+ return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
+#else
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
+ return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
+#endif
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
+ FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
+#else
+ FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
+#endif
+ return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
+#else
+ return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+#define EMIT_MOV(type, type_flags, type_cast) \
+ emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+ sljit_s32 op_flags = GET_ALL_FLAGS(op);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ op = GET_OPCODE(op);
+ if ((src & SLJIT_IMM) && srcw == 0)
+ src = TMP_ZERO;
+
+ if (op_flags & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
+
+ if (op_flags & SLJIT_I32_OP) {
+ if (op < SLJIT_NOT) {
+ if (FAST_IS_REG(src) && src == dst) {
+ if (!TYPE_CAST_NEEDED(op))
+ return SLJIT_SUCCESS;
+ }
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM))
+ op = SLJIT_MOV_U32;
+ if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM))
+ op = SLJIT_MOVU_U32;
+ if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM))
+ op = SLJIT_MOV_S32;
+ if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM))
+ op = SLJIT_MOVU_S32;
+#endif
+ }
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ else {
+ /* Most operations expect sign extended arguments. */
+ flags |= INT_DATA | SIGNED_DATA;
+ if (src & SLJIT_IMM)
+ srcw = (sljit_s32)srcw;
+ }
+#endif
+ }
+
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+#endif
+ return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ case SLJIT_MOV_U32:
+ return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));
+
+ case SLJIT_MOV_S32:
+ return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));
+#endif
+
+ case SLJIT_MOV_U8:
+ return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));
+
+ case SLJIT_MOV_S8:
+ return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));
+
+ case SLJIT_MOV_U16:
+ return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));
+
+ case SLJIT_MOV_S16:
+ return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16));
+
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_P:
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ case SLJIT_MOVU_U32:
+ case SLJIT_MOVU_S32:
+#endif
+ return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ case SLJIT_MOVU_U32:
+ return EMIT_MOV(SLJIT_MOV_U32, INT_DATA | WRITE_BACK, (sljit_u32));
+
+ case SLJIT_MOVU_S32:
+ return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s32));
+#endif
+
+ case SLJIT_MOVU_U8:
+ return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, (sljit_u8));
+
+ case SLJIT_MOVU_S8:
+ return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s8));
+
+ case SLJIT_MOVU_U16:
+ return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, (sljit_u16));
+
+ case SLJIT_MOVU_S16:
+ return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s16));
+
+ case SLJIT_NOT:
+ return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_CLZ:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+ return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw);
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+#undef EMIT_MOV
+
+#define TEST_SL_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
+
+#define TEST_UL_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_SH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
+#else
+#define TEST_SH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
+#endif
+
+#define TEST_UH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_ADD_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
+#else
+#define TEST_ADD_IMM(src, srcw) \
+ ((src) & SLJIT_IMM)
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_UI_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
+#else
+#define TEST_UI_IMM(src, srcw) \
+ ((src) & SLJIT_IMM)
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ if ((src1 & SLJIT_IMM) && src1w == 0)
+ src1 = TMP_ZERO;
+ if ((src2 & SLJIT_IMM) && src2w == 0)
+ src2 = TMP_ZERO;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_I32_OP) {
+ /* Most operations expect sign extended arguments. */
+ flags |= INT_DATA | SIGNED_DATA;
+ if (src1 & SLJIT_IMM)
+ src1w = (sljit_s32)(src1w);
+ if (src2 & SLJIT_IMM)
+ src2w = (sljit_s32)(src2w);
+ if (GET_FLAGS(op))
+ flags |= ALT_SIGN_EXT;
+ }
+#endif
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
+ if (src2 == TMP_REG2)
+ flags |= ALT_KEEP_CACHE;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src2, src2w)) {
+ compiler->imm = (src2w >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src1, src1w)) {
+ compiler->imm = (src1w >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ /* Range between -1 and -32768 is covered above. */
+ if (TEST_ADD_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_ADD_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_ADDC:
+ return emit_op(compiler, SLJIT_ADDC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+ if (TEST_SL_IMM(src2, -src2w)) {
+ compiler->imm = (-src2w) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src2, -src2w)) {
+ compiler->imm = ((-src2w) >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ /* Range between -1 and -32768 is covered above. */
+ if (TEST_ADD_IMM(src2, -src2w)) {
+ compiler->imm = -src2w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ }
+ if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) {
+ if (!(op & SLJIT_SET_U)) {
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) {
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
+ if (TEST_UL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
+ }
+ if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) {
+ compiler->imm = src2w;
+ return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, SLJIT_SUB, flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
+ }
+ if (!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))) {
+ if (TEST_SL_IMM(src2, -src2w)) {
+ compiler->imm = (-src2w) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ }
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
+ return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUBC:
+ return emit_op(compiler, SLJIT_SUBC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_I32_OP)
+ flags |= ALT_FORM2;
+#endif
+ if (!GET_FLAGS(op)) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ /* Commutative unsigned operations. */
+ if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
+ if (TEST_UL_IMM(src2, src2w)) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UL_IMM(src1, src1w)) {
+ compiler->imm = src1w;
+ return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_UH_IMM(src2, src2w)) {
+ compiler->imm = (src2w >> 16) & 0xffff;
+ return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UH_IMM(src1, src1w)) {
+ compiler->imm = (src1w >> 16) & 0xffff;
+ return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {
+ if (TEST_UI_IMM(src2, src2w)) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UI_IMM(src1, src1w)) {
+ compiler->imm = src1w;
+ return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_ASHR:
+ if (op & SLJIT_KEEP_FLAGS)
+ flags |= ALT_FORM3;
+ /* Fall through. */
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_I32_OP)
+ flags |= ALT_FORM2;
+#endif
+ if (src2 & SLJIT_IMM) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ return reg;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ return push_inst(compiler, *(sljit_ins*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+#ifdef SLJIT_IS_FPU_AVAILABLE
+ return SLJIT_IS_FPU_AVAILABLE;
+#else
+ /* Available by default. */
+ return 1;
+#endif
+}
+
+#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))
+#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
+#else
+#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
+
+#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
+#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
+#else
+#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
+#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
+#endif
+
+#endif /* SLJIT_CONFIG_PPC_64 */
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (src & SLJIT_MEM) {
+ /* We can ignore the temporary data store on the stack from caching point of view. */
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+ src = TMP_FREG1;
+ }
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ op = GET_OPCODE(op);
+ FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (op == SLJIT_CONV_SW_FROM_F64) {
+ if (FAST_IS_REG(dst)) {
+ FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0));
+ return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
+ }
+ return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
+ }
+
+#else
+ FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+#endif
+
+ if (FAST_IS_REG(dst)) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
+ FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
+ return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
+ }
+
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+
+ if (dst & OFFS_REG_MASK) {
+ dstw &= 0x3;
+ if (dstw) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
+#else
+ FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
+#endif
+ dstw = TMP_REG1;
+ }
+ else
+ dstw = OFFS_REG(dst);
+ }
+ else {
+ if ((dst & REG_MASK) && !dstw) {
+ dstw = dst & REG_MASK;
+ dst = 0;
+ }
+ else {
+ /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
+ FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
+ dstw = TMP_REG1;
+ }
+ }
+
+ return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (src & SLJIT_IMM) {
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
+ srcw = (sljit_s32)srcw;
+ FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+ src = TMP_REG1;
+ }
+ else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
+ else
+ FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
+ src = TMP_REG1;
+ }
+
+ if (FAST_IS_REG(src)) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
+ FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw));
+ }
+ else
+ FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+
+ FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
+ if (op & SLJIT_F32_OP)
+ return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
+ return SLJIT_SUCCESS;
+
+#else
+
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+ sljit_s32 invert_sign = 1;
+
+ if (src & SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
+ src = TMP_REG1;
+ invert_sign = 0;
+ }
+ else if (!FAST_IS_REG(src)) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
+ src = TMP_REG1;
+ }
+
+ /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
+ The double precision format has exactly 53 bit precision, so the lower 32 bit represents
+ the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
+ to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
+ point value, we need to substract 2^53 + 2^31 from the constructed value. */
+ FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
+ if (invert_sign)
+ FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI));
+ FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
+ FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
+ FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
+
+ FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
+ if (op & SLJIT_F32_OP)
+ return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
+ return SLJIT_SUCCESS;
+
+#endif
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+ src1 = TMP_FREG1;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
+ src2 = TMP_FREG2;
+ }
+
+ return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
+
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
+ op ^= SLJIT_F32_OP;
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
+
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
+ src = dst_r;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_CONV_F64_FROM_F32:
+ op ^= SLJIT_F32_OP;
+ if (op & SLJIT_F32_OP) {
+ FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
+ break;
+ }
+ /* Fall through. */
+ case SLJIT_MOV_F64:
+ if (src != dst_r) {
+ if (dst_r != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
+ else
+ dst_r = src;
+ }
+ break;
+ case SLJIT_NEG_F64:
+ FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
+ break;
+ case SLJIT_ABS_F64:
+ FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r, flags = 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
+
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1 = TMP_FREG1;
+ } else
+ flags |= ALT_FORM1;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2 = TMP_FREG2;
+ } else
+ flags |= ALT_FORM2;
+ }
+
+ if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & ALT_FORM1)
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+ else if (flags & ALT_FORM2)
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+
+ if (flags & ALT_FORM1)
+ src1 = TMP_FREG1;
+ if (flags & ALT_FORM2)
+ src2 = TMP_FREG2;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
+ break;
+
+ case SLJIT_SUB_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
+ break;
+
+ case SLJIT_MUL_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
+ break;
+
+ case SLJIT_DIV_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
+ break;
+ }
+
+ if (dst_r == TMP_FREG2)
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
+
+ return SLJIT_SUCCESS;
+}
+
+#undef FLOAT_DATA
+#undef SELECT_FOP
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, MFLR | D(dst));
+
+ /* Memory. */
+ FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, MTLR | S(src)));
+ else {
+ if (src & SLJIT_MEM)
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
+ FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
+ }
+ return push_inst(compiler, BLR);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+static sljit_ins get_bo_bi_flags(sljit_s32 type)
+{
+ switch (type) {
+ case SLJIT_EQUAL:
+ return (12 << 21) | (2 << 16);
+
+ case SLJIT_NOT_EQUAL:
+ return (4 << 21) | (2 << 16);
+
+ case SLJIT_LESS:
+ case SLJIT_LESS_F64:
+ return (12 << 21) | ((4 + 0) << 16);
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ return (4 << 21) | ((4 + 0) << 16);
+
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_F64:
+ return (12 << 21) | ((4 + 1) << 16);
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return (4 << 21) | ((4 + 1) << 16);
+
+ case SLJIT_SIG_LESS:
+ return (12 << 21) | (0 << 16);
+
+ case SLJIT_SIG_GREATER_EQUAL:
+ return (4 << 21) | (0 << 16);
+
+ case SLJIT_SIG_GREATER:
+ return (12 << 21) | (1 << 16);
+
+ case SLJIT_SIG_LESS_EQUAL:
+ return (4 << 21) | (1 << 16);
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_MUL_OVERFLOW:
+ return (12 << 21) | (3 << 16);
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ return (4 << 21) | (3 << 16);
+
+ case SLJIT_EQUAL_F64:
+ return (12 << 21) | ((4 + 2) << 16);
+
+ case SLJIT_NOT_EQUAL_F64:
+ return (4 << 21) | ((4 + 2) << 16);
+
+ case SLJIT_UNORDERED_F64:
+ return (12 << 21) | ((4 + 3) << 16);
+
+ case SLJIT_ORDERED_F64:
+ return (4 << 21) | ((4 + 3) << 16);
+
+ default:
+ SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+ return (20 << 21);
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ struct sljit_jump *jump;
+ sljit_ins bo_bi_flags;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ bo_bi_flags = get_bo_bi_flags(type & 0xff);
+ if (!bo_bi_flags)
+ return NULL;
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In PPC, we don't need to touch the arguments. */
+ if (type < SLJIT_JUMP)
+ jump->flags |= IS_COND;
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
+ if (type >= SLJIT_CALL0)
+ jump->flags |= IS_CALL;
+#endif
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
+ PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ struct sljit_jump *jump = NULL;
+ sljit_s32 src_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src)) {
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
+ if (type >= SLJIT_CALL0) {
+ FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
+ src_r = TMP_CALL_REG;
+ }
+ else
+ src_r = src;
+#else
+ src_r = src;
+#endif
+ } else if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR);
+ jump->u.target = srcw;
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
+ if (type >= SLJIT_CALL0)
+ jump->flags |= IS_CALL;
+#endif
+ FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
+ src_r = TMP_CALL_REG;
+ }
+ else {
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
+ src_r = TMP_CALL_REG;
+ }
+
+ FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
+ if (jump)
+ jump->addr = compiler->size;
+ return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
+}
+
+/* Get a bit from CR, all other bits are zeroed. */
+#define GET_CR_BIT(bit, dst) \
+ FAIL_IF(push_inst(compiler, MFCR | D(dst))); \
+ FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1)));
+
+#define INVERT_BIT(dst) \
+ FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1));
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ sljit_s32 reg, input_flags;
+ sljit_s32 flags = GET_ALL_FLAGS(op);
+ sljit_sw original_dstw = dstw;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ op = GET_OPCODE(op);
+ reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
+ ADJUST_LOCAL_OFFSET(src, srcw);
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ input_flags = (flags & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
+#else
+ input_flags = WORD_DATA;
+#endif
+ FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ switch (type & 0xff) {
+ case SLJIT_EQUAL:
+ GET_CR_BIT(2, reg);
+ break;
+
+ case SLJIT_NOT_EQUAL:
+ GET_CR_BIT(2, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_LESS:
+ case SLJIT_LESS_F64:
+ GET_CR_BIT(4 + 0, reg);
+ break;
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ GET_CR_BIT(4 + 0, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_F64:
+ GET_CR_BIT(4 + 1, reg);
+ break;
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ GET_CR_BIT(4 + 1, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_SIG_LESS:
+ GET_CR_BIT(0, reg);
+ break;
+
+ case SLJIT_SIG_GREATER_EQUAL:
+ GET_CR_BIT(0, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_SIG_GREATER:
+ GET_CR_BIT(1, reg);
+ break;
+
+ case SLJIT_SIG_LESS_EQUAL:
+ GET_CR_BIT(1, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_MUL_OVERFLOW:
+ GET_CR_BIT(3, reg);
+ break;
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ GET_CR_BIT(3, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_EQUAL_F64:
+ GET_CR_BIT(4 + 2, reg);
+ break;
+
+ case SLJIT_NOT_EQUAL_F64:
+ GET_CR_BIT(4 + 2, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_UNORDERED_F64:
+ GET_CR_BIT(4 + 3, reg);
+ break;
+
+ case SLJIT_ORDERED_F64:
+ GET_CR_BIT(4 + 3, reg);
+ INVERT_BIT(reg);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ if (op < SLJIT_ADD) {
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op == SLJIT_MOV)
+ input_flags = WORD_DATA;
+ else {
+ op = SLJIT_MOV_U32;
+ input_flags = INT_DATA;
+ }
+#else
+ op = SLJIT_MOV;
+ input_flags = WORD_DATA;
+#endif
+ if (reg != TMP_REG2)
+ return SLJIT_SUCCESS;
+ return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+ }
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_const *const_;
+ sljit_s32 reg;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ return const_;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
new file mode 100644
index 0000000000..4a206f11d0
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
@@ -0,0 +1,166 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw imm)
+{
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst));
+
+ FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((imm >> 10) & 0x3fffff), DR(dst)));
+ return (imm & 0x3ff) ? push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (imm & 0x3ff), DR(dst)) : SLJIT_SUCCESS;
+}
+
+#define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2))
+
+static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
+{
+ SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same);
+
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ case SLJIT_MOV_P:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (dst != src2)
+ return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_U8)
+ return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst));
+ FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst)));
+ return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst)));
+ return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ /* sparc 32 does not support SLJIT_KEEP_FLAGS. Not sure I can fix this. */
+ FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(src2) | S2(0), SET_FLAGS));
+ FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2(src2), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, BICC | DA(0x1) | (7 & DISP_MASK), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(0) | IMM(32), UNMOVABLE_INS | (flags & SET_FLAGS)));
+ FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(-1), DR(dst)));
+
+ /* Loop. */
+ FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(0), SET_FLAGS));
+ FAIL_IF(push_inst(compiler, SLL | D(TMP_REG1) | S1(TMP_REG1) | IMM(1), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, BICC | DA(0xe) | (-2 & DISP_MASK), UNMOVABLE_INS));
+ return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS | (flags & SET_FLAGS));
+
+ case SLJIT_ADD:
+ return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_ADDC:
+ return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_SUB:
+ return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_SUBC:
+ return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_MUL:
+ FAIL_IF(push_inst(compiler, SMUL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
+ if (!(flags & SET_FLAGS))
+ return SLJIT_SUCCESS;
+ FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(dst) | IMM(31), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, RDY | D(TMP_LINK), DR(TMP_LINK)));
+ return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_LINK), MOVABLE_INS | SET_FLAGS);
+
+ case SLJIT_AND:
+ return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_OR:
+ return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_XOR:
+ return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
+
+ case SLJIT_SHL:
+ FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
+ return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);
+
+ case SLJIT_LSHR:
+ FAIL_IF(push_inst(compiler, SRL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
+ return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);
+
+ case SLJIT_ASHR:
+ FAIL_IF(push_inst(compiler, SRA | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
+ return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
+{
+ FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst)));
+ return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
+ inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
+ inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
new file mode 100644
index 0000000000..7445fc4723
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
@@ -0,0 +1,1450 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "SPARC" SLJIT_CPUINFO;
+}
+
+/* Length of an instruction word
+ Both for sparc-32 and sparc-64 */
+typedef sljit_u32 sljit_ins;
+
+#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
+
+static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
+{
+#if defined(__SUNPRO_C) && __SUNPRO_C < 0x590
+ __asm (
+ /* if (from == to) return */
+ "cmp %i0, %i1\n"
+ "be .leave\n"
+ "nop\n"
+
+ /* loop until from >= to */
+ ".mainloop:\n"
+ "flush %i0\n"
+ "add %i0, 8, %i0\n"
+ "cmp %i0, %i1\n"
+ "bcs .mainloop\n"
+ "nop\n"
+
+ /* The comparison was done above. */
+ "bne .leave\n"
+ /* nop is not necessary here, since the
+ sub operation has no side effect. */
+ "sub %i0, 4, %i0\n"
+ "flush %i0\n"
+ ".leave:"
+ );
+#else
+ if (SLJIT_UNLIKELY(from == to))
+ return;
+
+ do {
+ __asm__ volatile (
+ "flush %0\n"
+ : : "r"(from)
+ );
+ /* Operates at least on doubleword. */
+ from += 2;
+ } while (from < to);
+
+ if (from == to) {
+ /* Flush the last word. */
+ from --;
+ __asm__ volatile (
+ "flush %0\n"
+ : : "r"(from)
+ );
+ }
+#endif
+}
+
+#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
+
+/* TMP_REG2 is not used by getput_arg */
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+#define TMP_LINK (SLJIT_NUMBER_OF_REGISTERS + 5)
+
+#define TMP_FREG1 (0)
+#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
+ 0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15
+};
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+#define D(d) (reg_map[d] << 25)
+#define DA(d) ((d) << 25)
+#define S1(s1) (reg_map[s1] << 14)
+#define S2(s2) (reg_map[s2])
+#define S1A(s1) ((s1) << 14)
+#define S2A(s2) (s2)
+#define IMM_ARG 0x2000
+#define DOP(op) ((op) << 5)
+#define IMM(imm) (((imm) & 0x1fff) | IMM_ARG)
+
+#define DR(dr) (reg_map[dr])
+#define OPC1(opcode) ((opcode) << 30)
+#define OPC2(opcode) ((opcode) << 22)
+#define OPC3(opcode) ((opcode) << 19)
+#define SET_FLAGS OPC3(0x10)
+
+#define ADD (OPC1(0x2) | OPC3(0x00))
+#define ADDC (OPC1(0x2) | OPC3(0x08))
+#define AND (OPC1(0x2) | OPC3(0x01))
+#define ANDN (OPC1(0x2) | OPC3(0x05))
+#define CALL (OPC1(0x1))
+#define FABSS (OPC1(0x2) | OPC3(0x34) | DOP(0x09))
+#define FADDD (OPC1(0x2) | OPC3(0x34) | DOP(0x42))
+#define FADDS (OPC1(0x2) | OPC3(0x34) | DOP(0x41))
+#define FCMPD (OPC1(0x2) | OPC3(0x35) | DOP(0x52))
+#define FCMPS (OPC1(0x2) | OPC3(0x35) | DOP(0x51))
+#define FDIVD (OPC1(0x2) | OPC3(0x34) | DOP(0x4e))
+#define FDIVS (OPC1(0x2) | OPC3(0x34) | DOP(0x4d))
+#define FDTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd2))
+#define FDTOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc6))
+#define FITOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc8))
+#define FITOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc4))
+#define FMOVS (OPC1(0x2) | OPC3(0x34) | DOP(0x01))
+#define FMULD (OPC1(0x2) | OPC3(0x34) | DOP(0x4a))
+#define FMULS (OPC1(0x2) | OPC3(0x34) | DOP(0x49))
+#define FNEGS (OPC1(0x2) | OPC3(0x34) | DOP(0x05))
+#define FSTOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc9))
+#define FSTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd1))
+#define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46))
+#define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45))
+#define JMPL (OPC1(0x2) | OPC3(0x38))
+#define NOP (OPC1(0x0) | OPC2(0x04))
+#define OR (OPC1(0x2) | OPC3(0x02))
+#define ORN (OPC1(0x2) | OPC3(0x06))
+#define RDY (OPC1(0x2) | OPC3(0x28) | S1A(0))
+#define RESTORE (OPC1(0x2) | OPC3(0x3d))
+#define SAVE (OPC1(0x2) | OPC3(0x3c))
+#define SETHI (OPC1(0x0) | OPC2(0x04))
+#define SLL (OPC1(0x2) | OPC3(0x25))
+#define SLLX (OPC1(0x2) | OPC3(0x25) | (1 << 12))
+#define SRA (OPC1(0x2) | OPC3(0x27))
+#define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12))
+#define SRL (OPC1(0x2) | OPC3(0x26))
+#define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12))
+#define SUB (OPC1(0x2) | OPC3(0x04))
+#define SUBC (OPC1(0x2) | OPC3(0x0c))
+#define TA (OPC1(0x2) | OPC3(0x3a) | (8 << 25))
+#define WRY (OPC1(0x2) | OPC3(0x30) | DA(0))
+#define XOR (OPC1(0x2) | OPC3(0x03))
+#define XNOR (OPC1(0x2) | OPC3(0x07))
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+#define MAX_DISP (0x1fffff)
+#define MIN_DISP (-0x200000)
+#define DISP_MASK (0x3fffff)
+
+#define BICC (OPC1(0x0) | OPC2(0x2))
+#define FBFCC (OPC1(0x0) | OPC2(0x6))
+#define SLL_W SLL
+#define SDIV (OPC1(0x2) | OPC3(0x0f))
+#define SMUL (OPC1(0x2) | OPC3(0x0b))
+#define UDIV (OPC1(0x2) | OPC3(0x0e))
+#define UMUL (OPC1(0x2) | OPC3(0x0a))
+#else
+#define SLL_W SLLX
+#endif
+
+#define SIMM_MAX (0x0fff)
+#define SIMM_MIN (-0x1000)
+
+/* dest_reg is the absolute name of the register
+ Useful for reordering instructions in the delay slot. */
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
+{
+ sljit_ins *ptr;
+ SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
+ || (delay_slot & DST_INS_MASK) == MOVABLE_INS
+ || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));
+ ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ compiler->delay_slot = delay_slot;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+{
+ sljit_sw diff;
+ sljit_uw target_addr;
+ sljit_ins *inst;
+ sljit_ins saved_inst;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return code_ptr;
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
+ }
+ inst = (sljit_ins*)jump->addr;
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ if (jump->flags & IS_CALL) {
+ /* Call is always patchable on sparc 32. */
+ jump->flags |= PATCH_CALL;
+ if (jump->flags & IS_MOVABLE) {
+ inst[0] = inst[-1];
+ inst[-1] = CALL;
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+ inst[0] = CALL;
+ inst[1] = NOP;
+ return inst + 1;
+ }
+#else
+ /* Both calls and BPr instructions shall not pass this point. */
+#error "Implementation required"
+#endif
+
+ if (jump->flags & IS_COND)
+ inst--;
+
+ diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1) - executable_offset) >> 2;
+
+ if (jump->flags & IS_MOVABLE) {
+ if (diff <= MAX_DISP && diff >= MIN_DISP) {
+ jump->flags |= PATCH_B;
+ inst--;
+ if (jump->flags & IS_COND) {
+ saved_inst = inst[0];
+ inst[0] = inst[1] ^ (1 << 28);
+ inst[1] = saved_inst;
+ } else {
+ inst[1] = inst[0];
+ inst[0] = BICC | DA(0x8);
+ }
+ jump->addr = (sljit_uw)inst;
+ return inst + 1;
+ }
+ }
+
+ diff += sizeof(sljit_ins);
+
+ if (diff <= MAX_DISP && diff >= MIN_DISP) {
+ jump->flags |= PATCH_B;
+ if (jump->flags & IS_COND)
+ inst[0] ^= (1 << 28);
+ else
+ inst[0] = BICC | DA(0x8);
+ inst[1] = NOP;
+ jump->addr = (sljit_uw)inst;
+ return inst + 1;
+ }
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_sw executable_offset;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ jump->addr = (sljit_uw)(code_ptr - 3);
+#else
+ jump->addr = (sljit_uw)(code_ptr - 6);
+#endif
+ code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins *)jump->addr;
+
+ if (jump->flags & PATCH_CALL) {
+ addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
+ SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
+ buf_ptr[0] = CALL | (addr & 0x3fffffff);
+ break;
+ }
+ if (jump->flags & PATCH_B) {
+ addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
+ SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
+ buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
+ break;
+ }
+
+ /* Set the fields of immediate loads. */
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff);
+#else
+#error "Implementation required"
+#endif
+ } while (0);
+ jump = jump->next;
+ }
+
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+
+ code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ return code;
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+/* Creates an index in data_transfer_insts array. */
+#define LOAD_DATA 0x01
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x02
+#define HALF_DATA 0x04
+#define INT_DATA 0x06
+#define SIGNED_DATA 0x08
+/* Separates integer and floating point registers */
+#define GPR_REG 0x0f
+#define DOUBLE_DATA 0x10
+#define SINGLE_DATA 0x12
+
+#define MEM_MASK 0x1f
+
+#define WRITE_BACK 0x00020
+#define ARG_TEST 0x00040
+#define ALT_KEEP_CACHE 0x00080
+#define CUMULATIVE_OP 0x00100
+#define IMM_OP 0x00200
+#define SRC2_IMM 0x00400
+
+#define REG_DEST 0x00800
+#define REG2_SOURCE 0x01000
+#define SLOW_SRC1 0x02000
+#define SLOW_SRC2 0x04000
+#define SLOW_DEST 0x08000
+
+/* SET_FLAGS (0x10 << 19) also belong here! */
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+#include "sljitNativeSPARC_32.c"
+#else
+#include "sljitNativeSPARC_64.c"
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
+ compiler->local_size = local_size;
+
+ if (local_size <= SIMM_MAX) {
+ FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS));
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size));
+ FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS));
+ }
+
+ /* Arguments are in their appropriate registers. */
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ if (op != SLJIT_MOV || !FAST_IS_REG(src)) {
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+ src = SLJIT_R0;
+ }
+
+ FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));
+ return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+#define ARCH_32_64(a, b) a
+#else
+#define ARCH_32_64(a, b) b
+#endif
+
+static const sljit_ins data_transfer_insts[16 + 4] = {
+/* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
+/* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
+/* u b s */ OPC1(3) | OPC3(0x05) /* stb */,
+/* u b l */ OPC1(3) | OPC3(0x01) /* ldub */,
+/* u h s */ OPC1(3) | OPC3(0x06) /* sth */,
+/* u h l */ OPC1(3) | OPC3(0x02) /* lduh */,
+/* u i s */ OPC1(3) | OPC3(0x04) /* stw */,
+/* u i l */ OPC1(3) | OPC3(0x00) /* lduw */,
+
+/* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
+/* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
+/* s b s */ OPC1(3) | OPC3(0x05) /* stb */,
+/* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */,
+/* s h s */ OPC1(3) | OPC3(0x06) /* sth */,
+/* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */,
+/* s i s */ OPC1(3) | OPC3(0x04) /* stw */,
+/* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */),
+
+/* d s */ OPC1(3) | OPC3(0x27),
+/* d l */ OPC1(3) | OPC3(0x23),
+/* s s */ OPC1(3) | OPC3(0x24),
+/* s l */ OPC1(3) | OPC3(0x20),
+};
+
+#undef ARCH_32_64
+
+/* Can perform an operation using at most 1 instruction. */
+static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) {
+ if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
+ || ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
+ /* Works for both absoulte and relative addresses (immediate case). */
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
+ | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg))
+ | S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
+ ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
+
+ /* Simple operation except for updates. */
+ if (arg & OFFS_REG_MASK) {
+ argw &= 0x3;
+ SLJIT_ASSERT(argw);
+ next_argw &= 0x3;
+ if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw)
+ return 1;
+ return 0;
+ }
+
+ if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))
+ return 1;
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_s32 base, arg2, delay_slot;
+ sljit_ins dest;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ base = arg & REG_MASK;
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ argw &= 0x3;
+ SLJIT_ASSERT(argw != 0);
+
+ /* Using the cache. */
+ if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw))
+ arg2 = TMP_REG3;
+ else {
+ if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
+ compiler->cache_argw = argw;
+ arg2 = TMP_REG3;
+ }
+ else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg))
+ arg2 = reg;
+ else /* It must be a mov operation, so tmp1 must be free to use. */
+ arg2 = TMP_REG1;
+ FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2)));
+ }
+ }
+ else {
+ /* Using the cache. */
+ if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ compiler->cache_argw = argw;
+ }
+ arg2 = TMP_REG3;
+ } else {
+ if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) {
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ arg2 = TMP_REG3;
+ }
+ else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base)
+ arg2 = reg;
+ else /* It must be a mov operation, so tmp1 must be free to use. */
+ arg2 = TMP_REG1;
+ FAIL_IF(load_immediate(compiler, arg2, argw));
+ }
+ }
+
+ dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg));
+ delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS;
+ if (!base)
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot);
+ if (!(flags & WRITE_BACK))
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot));
+ return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base));
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ return compiler->error;
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+}
+
+static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ sljit_s32 dst_r = TMP_REG2;
+ sljit_s32 src1_r;
+ sljit_sw src2_r = 0;
+ sljit_s32 sugg_src2_r = TMP_REG2;
+
+ if (!(flags & ALT_KEEP_CACHE)) {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ }
+
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ }
+ else if (FAST_IS_REG(dst)) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ sugg_src2_r = dst_r;
+ }
+ else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (flags & IMM_OP) {
+ if ((src2 & SLJIT_IMM) && src2w) {
+ if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) {
+ flags |= SRC2_IMM;
+ src2_r = src2w;
+ }
+ }
+ if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
+ if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) {
+ flags |= SRC2_IMM;
+ src2_r = src1w;
+
+ /* And swap arguments. */
+ src1 = src2;
+ src1w = src2w;
+ src2 = SLJIT_IMM;
+ /* src2w = src2_r unneeded. */
+ }
+ }
+ }
+
+ /* Source 1. */
+ if (FAST_IS_REG(src1))
+ src1_r = src1;
+ else if (src1 & SLJIT_IMM) {
+ if (src1w) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+ src1_r = TMP_REG1;
+ }
+ else
+ src1_r = 0;
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ src1_r = TMP_REG1;
+ }
+
+ /* Source 2. */
+ if (FAST_IS_REG(src2)) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ dst_r = src2_r;
+ }
+ else if (src2 & SLJIT_IMM) {
+ if (!(flags & SRC2_IMM)) {
+ if (src2w) {
+ FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
+ src2_r = sugg_src2_r;
+ }
+ else {
+ src2_r = 0;
+ if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
+ dst_r = 0;
+ }
+ }
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ src2_r = sugg_src2_r;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ SLJIT_ASSERT(src2_r == TMP_REG2);
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, flags, dst_r, dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ return push_inst(compiler, TA, UNMOVABLE_INS);
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
+ return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1));
+#else
+#error "Implementation required"
+#endif
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+ SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ if ((op | 0x2) == SLJIT_DIV_UW)
+ FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
+ else {
+ FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
+ }
+ if (op <= SLJIT_DIVMOD_SW)
+ FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
+ if (op >= SLJIT_DIV_UW)
+ return SLJIT_SUCCESS;
+ FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
+ return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1));
+#else
+#error "Implementation required"
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_U32:
+ return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_S32:
+ return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
+
+ case SLJIT_MOV_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
+
+ case SLJIT_MOV_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
+
+ case SLJIT_MOV_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
+
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_P:
+ return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_U32:
+ return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_S32:
+ return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
+
+ case SLJIT_MOVU_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
+
+ case SLJIT_MOVU_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
+
+ case SLJIT_MOVU_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
+
+ case SLJIT_NOT:
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ case SLJIT_MUL:
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ if (src2 & SLJIT_IMM)
+ src2w &= 0x1f;
+#else
+ SLJIT_ASSERT_STOP();
+#endif
+ return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ return reg << 1;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+#ifdef SLJIT_IS_FPU_AVAILABLE
+ return SLJIT_IS_FPU_AVAILABLE;
+#else
+ /* Available by default. */
+ return 1;
+#endif
+}
+
+#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
+#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
+#define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+ src = TMP_FREG1;
+ }
+ else
+ src <<= 1;
+
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS));
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst)) {
+ FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
+ return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET);
+ }
+
+ /* Store the integer value from a VFP register. */
+ return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+
+ if (src & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
+ srcw = (sljit_s32)srcw;
+#endif
+ FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ if (FAST_IS_REG(src)) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
+ src = SLJIT_MEM1(SLJIT_SP);
+ srcw = FLOAT_TMP_MEM_OFFSET;
+ }
+
+ FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+ src1 = TMP_FREG1;
+ }
+ else
+ src1 <<= 1;
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
+ src2 = TMP_FREG2;
+ }
+ else
+ src2 <<= 1;
+
+ return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
+
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
+ op ^= SLJIT_F32_OP;
+
+ dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+
+ if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
+ src = dst_r;
+ }
+ else
+ src <<= 1;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_F64:
+ if (src != dst_r) {
+ if (dst_r != TMP_FREG1) {
+ FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS));
+ if (!(op & SLJIT_F32_OP))
+ FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
+ }
+ else
+ dst_r = src;
+ }
+ break;
+ case SLJIT_NEG_F64:
+ FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS));
+ if (dst_r != src && !(op & SLJIT_F32_OP))
+ FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
+ break;
+ case SLJIT_ABS_F64:
+ FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS));
+ if (dst_r != src && !(op & SLJIT_F32_OP))
+ FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
+ break;
+ case SLJIT_CONV_F64_FROM_F32:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS));
+ op ^= SLJIT_F32_OP;
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r, flags = 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
+
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1 = TMP_FREG1;
+ } else
+ flags |= SLOW_SRC1;
+ }
+ else
+ src1 <<= 1;
+
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2 = TMP_FREG2;
+ } else
+ flags |= SLOW_SRC2;
+ }
+ else
+ src2 <<= 1;
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+
+ if (flags & SLOW_SRC1)
+ src1 = TMP_FREG1;
+ if (flags & SLOW_SRC2)
+ src2 = TMP_FREG2;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+ break;
+
+ case SLJIT_SUB_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+ break;
+
+ case SLJIT_MUL_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+ break;
+
+ case SLJIT_DIV_F64:
+ FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+ break;
+ }
+
+ if (dst_r == TMP_FREG2)
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
+
+ return SLJIT_SUCCESS;
+}
+
+#undef FLOAT_DATA
+#undef SELECT_FOP
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst));
+
+ /* Memory. */
+ return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_LINK, srcw));
+
+ FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ compiler->delay_slot = UNMOVABLE_INS;
+ return label;
+}
+
+static sljit_ins get_cc(sljit_s32 type)
+{
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ case SLJIT_NOT_EQUAL_F64: /* Unordered. */
+ return DA(0x1);
+
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_EQUAL_F64:
+ return DA(0x9);
+
+ case SLJIT_LESS:
+ case SLJIT_GREATER_F64: /* Unordered. */
+ return DA(0x5);
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return DA(0xd);
+
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_EQUAL_F64: /* Unordered. */
+ return DA(0xc);
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_F64:
+ return DA(0x4);
+
+ case SLJIT_SIG_LESS:
+ return DA(0x3);
+
+ case SLJIT_SIG_GREATER_EQUAL:
+ return DA(0xb);
+
+ case SLJIT_SIG_GREATER:
+ return DA(0xa);
+
+ case SLJIT_SIG_LESS_EQUAL:
+ return DA(0x2);
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_UNORDERED_F64:
+ return DA(0x7);
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_ORDERED_F64:
+ return DA(0xf);
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return DA(0x8);
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type < SLJIT_EQUAL_F64) {
+ jump->flags |= IS_COND;
+ if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))
+ jump->flags |= IS_MOVABLE;
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
+#else
+#error "Implementation required"
+#endif
+ }
+ else if (type < SLJIT_JUMP) {
+ jump->flags |= IS_COND;
+ if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET))
+ jump->flags |= IS_MOVABLE;
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
+#else
+#error "Implementation required"
+#endif
+ } else {
+ if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
+ jump->flags |= IS_MOVABLE;
+ if (type >= SLJIT_FAST_CALL)
+ jump->flags |= IS_CALL;
+ }
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ struct sljit_jump *jump = NULL;
+ sljit_s32 src_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ src_r = src;
+ else if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR);
+ jump->u.target = srcw;
+ if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
+ jump->flags |= IS_MOVABLE;
+ if (type >= SLJIT_FAST_CALL)
+ jump->flags |= IS_CALL;
+
+ FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ src_r = TMP_REG2;
+ }
+ else {
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
+ src_r = TMP_REG2;
+ }
+
+ FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS));
+ if (jump)
+ jump->addr = compiler->size;
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ sljit_s32 reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ op = GET_OPCODE(op);
+ reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
+ ADJUST_LOCAL_OFFSET(src, srcw);
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ type &= 0xff;
+ if (type < SLJIT_EQUAL_F64)
+ FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));
+ else
+ FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));
+
+ FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS));
+
+ if (op >= SLJIT_ADD)
+ return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
+
+ return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
+#else
+#error "Implementation required"
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ sljit_s32 reg;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
+ return const_;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c
new file mode 100644
index 0000000000..719632908c
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c
@@ -0,0 +1,10159 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* This code is owned by Tilera Corporation, and distributed as part
+ of multiple projects. In sljit, the code is under BSD licence. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define BFD_RELOC(x) R_##x
+
+/* Special registers. */
+#define TREG_LR 55
+#define TREG_SN 56
+#define TREG_ZERO 63
+
+/* Canonical name of each register. */
+const char *const tilegx_register_names[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+ "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+ "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr",
+ "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero"
+};
+
+enum
+{
+ R_NONE = 0,
+ R_TILEGX_NONE = 0,
+ R_TILEGX_64 = 1,
+ R_TILEGX_32 = 2,
+ R_TILEGX_16 = 3,
+ R_TILEGX_8 = 4,
+ R_TILEGX_64_PCREL = 5,
+ R_TILEGX_32_PCREL = 6,
+ R_TILEGX_16_PCREL = 7,
+ R_TILEGX_8_PCREL = 8,
+ R_TILEGX_HW0 = 9,
+ R_TILEGX_HW1 = 10,
+ R_TILEGX_HW2 = 11,
+ R_TILEGX_HW3 = 12,
+ R_TILEGX_HW0_LAST = 13,
+ R_TILEGX_HW1_LAST = 14,
+ R_TILEGX_HW2_LAST = 15,
+ R_TILEGX_COPY = 16,
+ R_TILEGX_GLOB_DAT = 17,
+ R_TILEGX_JMP_SLOT = 18,
+ R_TILEGX_RELATIVE = 19,
+ R_TILEGX_BROFF_X1 = 20,
+ R_TILEGX_JUMPOFF_X1 = 21,
+ R_TILEGX_JUMPOFF_X1_PLT = 22,
+ R_TILEGX_IMM8_X0 = 23,
+ R_TILEGX_IMM8_Y0 = 24,
+ R_TILEGX_IMM8_X1 = 25,
+ R_TILEGX_IMM8_Y1 = 26,
+ R_TILEGX_DEST_IMM8_X1 = 27,
+ R_TILEGX_MT_IMM14_X1 = 28,
+ R_TILEGX_MF_IMM14_X1 = 29,
+ R_TILEGX_MMSTART_X0 = 30,
+ R_TILEGX_MMEND_X0 = 31,
+ R_TILEGX_SHAMT_X0 = 32,
+ R_TILEGX_SHAMT_X1 = 33,
+ R_TILEGX_SHAMT_Y0 = 34,
+ R_TILEGX_SHAMT_Y1 = 35,
+ R_TILEGX_IMM16_X0_HW0 = 36,
+ R_TILEGX_IMM16_X1_HW0 = 37,
+ R_TILEGX_IMM16_X0_HW1 = 38,
+ R_TILEGX_IMM16_X1_HW1 = 39,
+ R_TILEGX_IMM16_X0_HW2 = 40,
+ R_TILEGX_IMM16_X1_HW2 = 41,
+ R_TILEGX_IMM16_X0_HW3 = 42,
+ R_TILEGX_IMM16_X1_HW3 = 43,
+ R_TILEGX_IMM16_X0_HW0_LAST = 44,
+ R_TILEGX_IMM16_X1_HW0_LAST = 45,
+ R_TILEGX_IMM16_X0_HW1_LAST = 46,
+ R_TILEGX_IMM16_X1_HW1_LAST = 47,
+ R_TILEGX_IMM16_X0_HW2_LAST = 48,
+ R_TILEGX_IMM16_X1_HW2_LAST = 49,
+ R_TILEGX_IMM16_X0_HW0_PCREL = 50,
+ R_TILEGX_IMM16_X1_HW0_PCREL = 51,
+ R_TILEGX_IMM16_X0_HW1_PCREL = 52,
+ R_TILEGX_IMM16_X1_HW1_PCREL = 53,
+ R_TILEGX_IMM16_X0_HW2_PCREL = 54,
+ R_TILEGX_IMM16_X1_HW2_PCREL = 55,
+ R_TILEGX_IMM16_X0_HW3_PCREL = 56,
+ R_TILEGX_IMM16_X1_HW3_PCREL = 57,
+ R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58,
+ R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59,
+ R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60,
+ R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61,
+ R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62,
+ R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63,
+ R_TILEGX_IMM16_X0_HW0_GOT = 64,
+ R_TILEGX_IMM16_X1_HW0_GOT = 65,
+
+ R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66,
+ R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67,
+ R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68,
+ R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69,
+ R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70,
+ R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71,
+
+ R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72,
+ R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73,
+ R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74,
+ R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75,
+ R_TILEGX_IMM16_X0_HW0_TLS_GD = 78,
+ R_TILEGX_IMM16_X1_HW0_TLS_GD = 79,
+ R_TILEGX_IMM16_X0_HW0_TLS_LE = 80,
+ R_TILEGX_IMM16_X1_HW0_TLS_LE = 81,
+ R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82,
+ R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83,
+ R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84,
+ R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85,
+ R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86,
+ R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87,
+ R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88,
+ R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89,
+ R_TILEGX_IMM16_X0_HW0_TLS_IE = 92,
+ R_TILEGX_IMM16_X1_HW0_TLS_IE = 93,
+
+ R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94,
+ R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95,
+ R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96,
+ R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97,
+ R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98,
+ R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99,
+
+ R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100,
+ R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101,
+ R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102,
+ R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103,
+ R_TILEGX_TLS_DTPMOD64 = 106,
+ R_TILEGX_TLS_DTPOFF64 = 107,
+ R_TILEGX_TLS_TPOFF64 = 108,
+ R_TILEGX_TLS_DTPMOD32 = 109,
+ R_TILEGX_TLS_DTPOFF32 = 110,
+ R_TILEGX_TLS_TPOFF32 = 111,
+ R_TILEGX_TLS_GD_CALL = 112,
+ R_TILEGX_IMM8_X0_TLS_GD_ADD = 113,
+ R_TILEGX_IMM8_X1_TLS_GD_ADD = 114,
+ R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115,
+ R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116,
+ R_TILEGX_TLS_IE_LOAD = 117,
+ R_TILEGX_IMM8_X0_TLS_ADD = 118,
+ R_TILEGX_IMM8_X1_TLS_ADD = 119,
+ R_TILEGX_IMM8_Y0_TLS_ADD = 120,
+ R_TILEGX_IMM8_Y1_TLS_ADD = 121,
+ R_TILEGX_GNU_VTINHERIT = 128,
+ R_TILEGX_GNU_VTENTRY = 129,
+ R_TILEGX_IRELATIVE = 130,
+ R_TILEGX_NUM = 131
+};
+
+typedef enum
+{
+ TILEGX_PIPELINE_X0,
+ TILEGX_PIPELINE_X1,
+ TILEGX_PIPELINE_Y0,
+ TILEGX_PIPELINE_Y1,
+ TILEGX_PIPELINE_Y2,
+} tilegx_pipeline;
+
+typedef unsigned long long tilegx_bundle_bits;
+
+/* These are the bits that determine if a bundle is in the X encoding. */
+#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
+
+enum
+{
+ /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
+ TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
+
+ /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
+ TILEGX_NUM_PIPELINE_ENCODINGS = 5,
+
+ /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
+ TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
+
+ /* Instructions take this many bytes. */
+ TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
+
+ /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
+ TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
+
+ /* Bundles should be aligned modulo this number of bytes. */
+ TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
+ (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
+
+ /* Number of registers (some are magic, such as network I/O). */
+ TILEGX_NUM_REGISTERS = 64,
+};
+
+/* Make a few "tile_" variables to simplify common code between
+ architectures. */
+
+typedef tilegx_bundle_bits tile_bundle_bits;
+#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES
+#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
+#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
+ TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
+
+/* 64-bit pattern for a { bpt ; nop } bundle. */
+#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
+
+typedef enum
+{
+ TILEGX_OP_TYPE_REGISTER,
+ TILEGX_OP_TYPE_IMMEDIATE,
+ TILEGX_OP_TYPE_ADDRESS,
+ TILEGX_OP_TYPE_SPR
+} tilegx_operand_type;
+
+struct tilegx_operand
+{
+ /* Is this operand a register, immediate or address? */
+ tilegx_operand_type type;
+
+ /* The default relocation type for this operand. */
+ signed int default_reloc : 16;
+
+ /* How many bits is this value? (used for range checking) */
+ unsigned int num_bits : 5;
+
+ /* Is the value signed? (used for range checking) */
+ unsigned int is_signed : 1;
+
+ /* Is this operand a source register? */
+ unsigned int is_src_reg : 1;
+
+ /* Is this operand written? (i.e. is it a destination register) */
+ unsigned int is_dest_reg : 1;
+
+ /* Is this operand PC-relative? */
+ unsigned int is_pc_relative : 1;
+
+ /* By how many bits do we right shift the value before inserting? */
+ unsigned int rightshift : 2;
+
+ /* Return the bits for this operand to be ORed into an existing bundle. */
+ tilegx_bundle_bits (*insert) (int op);
+
+ /* Extract this operand and return it. */
+ unsigned int (*extract) (tilegx_bundle_bits bundle);
+};
+
+typedef enum
+{
+ TILEGX_OPC_BPT,
+ TILEGX_OPC_INFO,
+ TILEGX_OPC_INFOL,
+ TILEGX_OPC_LD4S_TLS,
+ TILEGX_OPC_LD_TLS,
+ TILEGX_OPC_MOVE,
+ TILEGX_OPC_MOVEI,
+ TILEGX_OPC_MOVELI,
+ TILEGX_OPC_PREFETCH,
+ TILEGX_OPC_PREFETCH_ADD_L1,
+ TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
+ TILEGX_OPC_PREFETCH_ADD_L2,
+ TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
+ TILEGX_OPC_PREFETCH_ADD_L3,
+ TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ TILEGX_OPC_PREFETCH_L1,
+ TILEGX_OPC_PREFETCH_L1_FAULT,
+ TILEGX_OPC_PREFETCH_L2,
+ TILEGX_OPC_PREFETCH_L2_FAULT,
+ TILEGX_OPC_PREFETCH_L3,
+ TILEGX_OPC_PREFETCH_L3_FAULT,
+ TILEGX_OPC_RAISE,
+ TILEGX_OPC_ADD,
+ TILEGX_OPC_ADDI,
+ TILEGX_OPC_ADDLI,
+ TILEGX_OPC_ADDX,
+ TILEGX_OPC_ADDXI,
+ TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXSC,
+ TILEGX_OPC_AND,
+ TILEGX_OPC_ANDI,
+ TILEGX_OPC_BEQZ,
+ TILEGX_OPC_BEQZT,
+ TILEGX_OPC_BFEXTS,
+ TILEGX_OPC_BFEXTU,
+ TILEGX_OPC_BFINS,
+ TILEGX_OPC_BGEZ,
+ TILEGX_OPC_BGEZT,
+ TILEGX_OPC_BGTZ,
+ TILEGX_OPC_BGTZT,
+ TILEGX_OPC_BLBC,
+ TILEGX_OPC_BLBCT,
+ TILEGX_OPC_BLBS,
+ TILEGX_OPC_BLBST,
+ TILEGX_OPC_BLEZ,
+ TILEGX_OPC_BLEZT,
+ TILEGX_OPC_BLTZ,
+ TILEGX_OPC_BLTZT,
+ TILEGX_OPC_BNEZ,
+ TILEGX_OPC_BNEZT,
+ TILEGX_OPC_CLZ,
+ TILEGX_OPC_CMOVEQZ,
+ TILEGX_OPC_CMOVNEZ,
+ TILEGX_OPC_CMPEQ,
+ TILEGX_OPC_CMPEQI,
+ TILEGX_OPC_CMPEXCH,
+ TILEGX_OPC_CMPEXCH4,
+ TILEGX_OPC_CMPLES,
+ TILEGX_OPC_CMPLEU,
+ TILEGX_OPC_CMPLTS,
+ TILEGX_OPC_CMPLTSI,
+ TILEGX_OPC_CMPLTU,
+ TILEGX_OPC_CMPLTUI,
+ TILEGX_OPC_CMPNE,
+ TILEGX_OPC_CMUL,
+ TILEGX_OPC_CMULA,
+ TILEGX_OPC_CMULAF,
+ TILEGX_OPC_CMULF,
+ TILEGX_OPC_CMULFR,
+ TILEGX_OPC_CMULH,
+ TILEGX_OPC_CMULHR,
+ TILEGX_OPC_CRC32_32,
+ TILEGX_OPC_CRC32_8,
+ TILEGX_OPC_CTZ,
+ TILEGX_OPC_DBLALIGN,
+ TILEGX_OPC_DBLALIGN2,
+ TILEGX_OPC_DBLALIGN4,
+ TILEGX_OPC_DBLALIGN6,
+ TILEGX_OPC_DRAIN,
+ TILEGX_OPC_DTLBPR,
+ TILEGX_OPC_EXCH,
+ TILEGX_OPC_EXCH4,
+ TILEGX_OPC_FDOUBLE_ADD_FLAGS,
+ TILEGX_OPC_FDOUBLE_ADDSUB,
+ TILEGX_OPC_FDOUBLE_MUL_FLAGS,
+ TILEGX_OPC_FDOUBLE_PACK1,
+ TILEGX_OPC_FDOUBLE_PACK2,
+ TILEGX_OPC_FDOUBLE_SUB_FLAGS,
+ TILEGX_OPC_FDOUBLE_UNPACK_MAX,
+ TILEGX_OPC_FDOUBLE_UNPACK_MIN,
+ TILEGX_OPC_FETCHADD,
+ TILEGX_OPC_FETCHADD4,
+ TILEGX_OPC_FETCHADDGEZ,
+ TILEGX_OPC_FETCHADDGEZ4,
+ TILEGX_OPC_FETCHAND,
+ TILEGX_OPC_FETCHAND4,
+ TILEGX_OPC_FETCHOR,
+ TILEGX_OPC_FETCHOR4,
+ TILEGX_OPC_FINV,
+ TILEGX_OPC_FLUSH,
+ TILEGX_OPC_FLUSHWB,
+ TILEGX_OPC_FNOP,
+ TILEGX_OPC_FSINGLE_ADD1,
+ TILEGX_OPC_FSINGLE_ADDSUB2,
+ TILEGX_OPC_FSINGLE_MUL1,
+ TILEGX_OPC_FSINGLE_MUL2,
+ TILEGX_OPC_FSINGLE_PACK1,
+ TILEGX_OPC_FSINGLE_PACK2,
+ TILEGX_OPC_FSINGLE_SUB1,
+ TILEGX_OPC_ICOH,
+ TILEGX_OPC_ILL,
+ TILEGX_OPC_INV,
+ TILEGX_OPC_IRET,
+ TILEGX_OPC_J,
+ TILEGX_OPC_JAL,
+ TILEGX_OPC_JALR,
+ TILEGX_OPC_JALRP,
+ TILEGX_OPC_JR,
+ TILEGX_OPC_JRP,
+ TILEGX_OPC_LD,
+ TILEGX_OPC_LD1S,
+ TILEGX_OPC_LD1S_ADD,
+ TILEGX_OPC_LD1U,
+ TILEGX_OPC_LD1U_ADD,
+ TILEGX_OPC_LD2S,
+ TILEGX_OPC_LD2S_ADD,
+ TILEGX_OPC_LD2U,
+ TILEGX_OPC_LD2U_ADD,
+ TILEGX_OPC_LD4S,
+ TILEGX_OPC_LD4S_ADD,
+ TILEGX_OPC_LD4U,
+ TILEGX_OPC_LD4U_ADD,
+ TILEGX_OPC_LD_ADD,
+ TILEGX_OPC_LDNA,
+ TILEGX_OPC_LDNA_ADD,
+ TILEGX_OPC_LDNT,
+ TILEGX_OPC_LDNT1S,
+ TILEGX_OPC_LDNT1S_ADD,
+ TILEGX_OPC_LDNT1U,
+ TILEGX_OPC_LDNT1U_ADD,
+ TILEGX_OPC_LDNT2S,
+ TILEGX_OPC_LDNT2S_ADD,
+ TILEGX_OPC_LDNT2U,
+ TILEGX_OPC_LDNT2U_ADD,
+ TILEGX_OPC_LDNT4S,
+ TILEGX_OPC_LDNT4S_ADD,
+ TILEGX_OPC_LDNT4U,
+ TILEGX_OPC_LDNT4U_ADD,
+ TILEGX_OPC_LDNT_ADD,
+ TILEGX_OPC_LNK,
+ TILEGX_OPC_MF,
+ TILEGX_OPC_MFSPR,
+ TILEGX_OPC_MM,
+ TILEGX_OPC_MNZ,
+ TILEGX_OPC_MTSPR,
+ TILEGX_OPC_MUL_HS_HS,
+ TILEGX_OPC_MUL_HS_HU,
+ TILEGX_OPC_MUL_HS_LS,
+ TILEGX_OPC_MUL_HS_LU,
+ TILEGX_OPC_MUL_HU_HU,
+ TILEGX_OPC_MUL_HU_LS,
+ TILEGX_OPC_MUL_HU_LU,
+ TILEGX_OPC_MUL_LS_LS,
+ TILEGX_OPC_MUL_LS_LU,
+ TILEGX_OPC_MUL_LU_LU,
+ TILEGX_OPC_MULA_HS_HS,
+ TILEGX_OPC_MULA_HS_HU,
+ TILEGX_OPC_MULA_HS_LS,
+ TILEGX_OPC_MULA_HS_LU,
+ TILEGX_OPC_MULA_HU_HU,
+ TILEGX_OPC_MULA_HU_LS,
+ TILEGX_OPC_MULA_HU_LU,
+ TILEGX_OPC_MULA_LS_LS,
+ TILEGX_OPC_MULA_LS_LU,
+ TILEGX_OPC_MULA_LU_LU,
+ TILEGX_OPC_MULAX,
+ TILEGX_OPC_MULX,
+ TILEGX_OPC_MZ,
+ TILEGX_OPC_NAP,
+ TILEGX_OPC_NOP,
+ TILEGX_OPC_NOR,
+ TILEGX_OPC_OR,
+ TILEGX_OPC_ORI,
+ TILEGX_OPC_PCNT,
+ TILEGX_OPC_REVBITS,
+ TILEGX_OPC_REVBYTES,
+ TILEGX_OPC_ROTL,
+ TILEGX_OPC_ROTLI,
+ TILEGX_OPC_SHL,
+ TILEGX_OPC_SHL16INSLI,
+ TILEGX_OPC_SHL1ADD,
+ TILEGX_OPC_SHL1ADDX,
+ TILEGX_OPC_SHL2ADD,
+ TILEGX_OPC_SHL2ADDX,
+ TILEGX_OPC_SHL3ADD,
+ TILEGX_OPC_SHL3ADDX,
+ TILEGX_OPC_SHLI,
+ TILEGX_OPC_SHLX,
+ TILEGX_OPC_SHLXI,
+ TILEGX_OPC_SHRS,
+ TILEGX_OPC_SHRSI,
+ TILEGX_OPC_SHRU,
+ TILEGX_OPC_SHRUI,
+ TILEGX_OPC_SHRUX,
+ TILEGX_OPC_SHRUXI,
+ TILEGX_OPC_SHUFFLEBYTES,
+ TILEGX_OPC_ST,
+ TILEGX_OPC_ST1,
+ TILEGX_OPC_ST1_ADD,
+ TILEGX_OPC_ST2,
+ TILEGX_OPC_ST2_ADD,
+ TILEGX_OPC_ST4,
+ TILEGX_OPC_ST4_ADD,
+ TILEGX_OPC_ST_ADD,
+ TILEGX_OPC_STNT,
+ TILEGX_OPC_STNT1,
+ TILEGX_OPC_STNT1_ADD,
+ TILEGX_OPC_STNT2,
+ TILEGX_OPC_STNT2_ADD,
+ TILEGX_OPC_STNT4,
+ TILEGX_OPC_STNT4_ADD,
+ TILEGX_OPC_STNT_ADD,
+ TILEGX_OPC_SUB,
+ TILEGX_OPC_SUBX,
+ TILEGX_OPC_SUBXSC,
+ TILEGX_OPC_SWINT0,
+ TILEGX_OPC_SWINT1,
+ TILEGX_OPC_SWINT2,
+ TILEGX_OPC_SWINT3,
+ TILEGX_OPC_TBLIDXB0,
+ TILEGX_OPC_TBLIDXB1,
+ TILEGX_OPC_TBLIDXB2,
+ TILEGX_OPC_TBLIDXB3,
+ TILEGX_OPC_V1ADD,
+ TILEGX_OPC_V1ADDI,
+ TILEGX_OPC_V1ADDUC,
+ TILEGX_OPC_V1ADIFFU,
+ TILEGX_OPC_V1AVGU,
+ TILEGX_OPC_V1CMPEQ,
+ TILEGX_OPC_V1CMPEQI,
+ TILEGX_OPC_V1CMPLES,
+ TILEGX_OPC_V1CMPLEU,
+ TILEGX_OPC_V1CMPLTS,
+ TILEGX_OPC_V1CMPLTSI,
+ TILEGX_OPC_V1CMPLTU,
+ TILEGX_OPC_V1CMPLTUI,
+ TILEGX_OPC_V1CMPNE,
+ TILEGX_OPC_V1DDOTPU,
+ TILEGX_OPC_V1DDOTPUA,
+ TILEGX_OPC_V1DDOTPUS,
+ TILEGX_OPC_V1DDOTPUSA,
+ TILEGX_OPC_V1DOTP,
+ TILEGX_OPC_V1DOTPA,
+ TILEGX_OPC_V1DOTPU,
+ TILEGX_OPC_V1DOTPUA,
+ TILEGX_OPC_V1DOTPUS,
+ TILEGX_OPC_V1DOTPUSA,
+ TILEGX_OPC_V1INT_H,
+ TILEGX_OPC_V1INT_L,
+ TILEGX_OPC_V1MAXU,
+ TILEGX_OPC_V1MAXUI,
+ TILEGX_OPC_V1MINU,
+ TILEGX_OPC_V1MINUI,
+ TILEGX_OPC_V1MNZ,
+ TILEGX_OPC_V1MULTU,
+ TILEGX_OPC_V1MULU,
+ TILEGX_OPC_V1MULUS,
+ TILEGX_OPC_V1MZ,
+ TILEGX_OPC_V1SADAU,
+ TILEGX_OPC_V1SADU,
+ TILEGX_OPC_V1SHL,
+ TILEGX_OPC_V1SHLI,
+ TILEGX_OPC_V1SHRS,
+ TILEGX_OPC_V1SHRSI,
+ TILEGX_OPC_V1SHRU,
+ TILEGX_OPC_V1SHRUI,
+ TILEGX_OPC_V1SUB,
+ TILEGX_OPC_V1SUBUC,
+ TILEGX_OPC_V2ADD,
+ TILEGX_OPC_V2ADDI,
+ TILEGX_OPC_V2ADDSC,
+ TILEGX_OPC_V2ADIFFS,
+ TILEGX_OPC_V2AVGS,
+ TILEGX_OPC_V2CMPEQ,
+ TILEGX_OPC_V2CMPEQI,
+ TILEGX_OPC_V2CMPLES,
+ TILEGX_OPC_V2CMPLEU,
+ TILEGX_OPC_V2CMPLTS,
+ TILEGX_OPC_V2CMPLTSI,
+ TILEGX_OPC_V2CMPLTU,
+ TILEGX_OPC_V2CMPLTUI,
+ TILEGX_OPC_V2CMPNE,
+ TILEGX_OPC_V2DOTP,
+ TILEGX_OPC_V2DOTPA,
+ TILEGX_OPC_V2INT_H,
+ TILEGX_OPC_V2INT_L,
+ TILEGX_OPC_V2MAXS,
+ TILEGX_OPC_V2MAXSI,
+ TILEGX_OPC_V2MINS,
+ TILEGX_OPC_V2MINSI,
+ TILEGX_OPC_V2MNZ,
+ TILEGX_OPC_V2MULFSC,
+ TILEGX_OPC_V2MULS,
+ TILEGX_OPC_V2MULTS,
+ TILEGX_OPC_V2MZ,
+ TILEGX_OPC_V2PACKH,
+ TILEGX_OPC_V2PACKL,
+ TILEGX_OPC_V2PACKUC,
+ TILEGX_OPC_V2SADAS,
+ TILEGX_OPC_V2SADAU,
+ TILEGX_OPC_V2SADS,
+ TILEGX_OPC_V2SADU,
+ TILEGX_OPC_V2SHL,
+ TILEGX_OPC_V2SHLI,
+ TILEGX_OPC_V2SHLSC,
+ TILEGX_OPC_V2SHRS,
+ TILEGX_OPC_V2SHRSI,
+ TILEGX_OPC_V2SHRU,
+ TILEGX_OPC_V2SHRUI,
+ TILEGX_OPC_V2SUB,
+ TILEGX_OPC_V2SUBSC,
+ TILEGX_OPC_V4ADD,
+ TILEGX_OPC_V4ADDSC,
+ TILEGX_OPC_V4INT_H,
+ TILEGX_OPC_V4INT_L,
+ TILEGX_OPC_V4PACKSC,
+ TILEGX_OPC_V4SHL,
+ TILEGX_OPC_V4SHLSC,
+ TILEGX_OPC_V4SHRS,
+ TILEGX_OPC_V4SHRU,
+ TILEGX_OPC_V4SUB,
+ TILEGX_OPC_V4SUBSC,
+ TILEGX_OPC_WH64,
+ TILEGX_OPC_XOR,
+ TILEGX_OPC_XORI,
+ TILEGX_OPC_NONE
+} tilegx_mnemonic;
+
+enum
+{
+ TILEGX_MAX_OPERANDS = 4 /* bfexts */
+};
+
+struct tilegx_opcode
+{
+ /* The opcode mnemonic, e.g. "add" */
+ const char *name;
+
+ /* The enum value for this mnemonic. */
+ tilegx_mnemonic mnemonic;
+
+ /* A bit mask of which of the five pipes this instruction
+ is compatible with:
+ X0 0x01
+ X1 0x02
+ Y0 0x04
+ Y1 0x08
+ Y2 0x10 */
+ unsigned char pipes;
+
+ /* How many operands are there? */
+ unsigned char num_operands;
+
+ /* Which register does this write implicitly, or TREG_ZERO if none? */
+ unsigned char implicitly_written_register;
+
+ /* Can this be bundled with other instructions (almost always true). */
+ unsigned char can_bundle;
+
+ /* The description of the operands. Each of these is an
+ * index into the tilegx_operands[] table. */
+ unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
+
+ /* A mask of which bits have predefined values for each pipeline.
+ * This is useful for disassembly. */
+ tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS];
+
+ /* For each bit set in fixed_bit_masks, what the value is for this
+ * instruction. */
+ tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS];
+};
+
+/* Used for non-textual disassembly into structs. */
+struct tilegx_decoded_instruction
+{
+ const struct tilegx_opcode *opcode;
+ const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
+ long long operand_values[TILEGX_MAX_OPERANDS];
+};
+
+enum
+{
+ ADDI_IMM8_OPCODE_X0 = 1,
+ ADDI_IMM8_OPCODE_X1 = 1,
+ ADDI_OPCODE_Y0 = 0,
+ ADDI_OPCODE_Y1 = 1,
+ ADDLI_OPCODE_X0 = 1,
+ ADDLI_OPCODE_X1 = 0,
+ ADDXI_IMM8_OPCODE_X0 = 2,
+ ADDXI_IMM8_OPCODE_X1 = 2,
+ ADDXI_OPCODE_Y0 = 1,
+ ADDXI_OPCODE_Y1 = 2,
+ ADDXLI_OPCODE_X0 = 2,
+ ADDXLI_OPCODE_X1 = 1,
+ ADDXSC_RRR_0_OPCODE_X0 = 1,
+ ADDXSC_RRR_0_OPCODE_X1 = 1,
+ ADDX_RRR_0_OPCODE_X0 = 2,
+ ADDX_RRR_0_OPCODE_X1 = 2,
+ ADDX_RRR_0_OPCODE_Y0 = 0,
+ ADDX_SPECIAL_0_OPCODE_Y1 = 0,
+ ADD_RRR_0_OPCODE_X0 = 3,
+ ADD_RRR_0_OPCODE_X1 = 3,
+ ADD_RRR_0_OPCODE_Y0 = 1,
+ ADD_SPECIAL_0_OPCODE_Y1 = 1,
+ ANDI_IMM8_OPCODE_X0 = 3,
+ ANDI_IMM8_OPCODE_X1 = 3,
+ ANDI_OPCODE_Y0 = 2,
+ ANDI_OPCODE_Y1 = 3,
+ AND_RRR_0_OPCODE_X0 = 4,
+ AND_RRR_0_OPCODE_X1 = 4,
+ AND_RRR_5_OPCODE_Y0 = 0,
+ AND_RRR_5_OPCODE_Y1 = 0,
+ BEQZT_BRANCH_OPCODE_X1 = 16,
+ BEQZ_BRANCH_OPCODE_X1 = 17,
+ BFEXTS_BF_OPCODE_X0 = 4,
+ BFEXTU_BF_OPCODE_X0 = 5,
+ BFINS_BF_OPCODE_X0 = 6,
+ BF_OPCODE_X0 = 3,
+ BGEZT_BRANCH_OPCODE_X1 = 18,
+ BGEZ_BRANCH_OPCODE_X1 = 19,
+ BGTZT_BRANCH_OPCODE_X1 = 20,
+ BGTZ_BRANCH_OPCODE_X1 = 21,
+ BLBCT_BRANCH_OPCODE_X1 = 22,
+ BLBC_BRANCH_OPCODE_X1 = 23,
+ BLBST_BRANCH_OPCODE_X1 = 24,
+ BLBS_BRANCH_OPCODE_X1 = 25,
+ BLEZT_BRANCH_OPCODE_X1 = 26,
+ BLEZ_BRANCH_OPCODE_X1 = 27,
+ BLTZT_BRANCH_OPCODE_X1 = 28,
+ BLTZ_BRANCH_OPCODE_X1 = 29,
+ BNEZT_BRANCH_OPCODE_X1 = 30,
+ BNEZ_BRANCH_OPCODE_X1 = 31,
+ BRANCH_OPCODE_X1 = 2,
+ CMOVEQZ_RRR_0_OPCODE_X0 = 5,
+ CMOVEQZ_RRR_4_OPCODE_Y0 = 0,
+ CMOVNEZ_RRR_0_OPCODE_X0 = 6,
+ CMOVNEZ_RRR_4_OPCODE_Y0 = 1,
+ CMPEQI_IMM8_OPCODE_X0 = 4,
+ CMPEQI_IMM8_OPCODE_X1 = 4,
+ CMPEQI_OPCODE_Y0 = 3,
+ CMPEQI_OPCODE_Y1 = 4,
+ CMPEQ_RRR_0_OPCODE_X0 = 7,
+ CMPEQ_RRR_0_OPCODE_X1 = 5,
+ CMPEQ_RRR_3_OPCODE_Y0 = 0,
+ CMPEQ_RRR_3_OPCODE_Y1 = 2,
+ CMPEXCH4_RRR_0_OPCODE_X1 = 6,
+ CMPEXCH_RRR_0_OPCODE_X1 = 7,
+ CMPLES_RRR_0_OPCODE_X0 = 8,
+ CMPLES_RRR_0_OPCODE_X1 = 8,
+ CMPLES_RRR_2_OPCODE_Y0 = 0,
+ CMPLES_RRR_2_OPCODE_Y1 = 0,
+ CMPLEU_RRR_0_OPCODE_X0 = 9,
+ CMPLEU_RRR_0_OPCODE_X1 = 9,
+ CMPLEU_RRR_2_OPCODE_Y0 = 1,
+ CMPLEU_RRR_2_OPCODE_Y1 = 1,
+ CMPLTSI_IMM8_OPCODE_X0 = 5,
+ CMPLTSI_IMM8_OPCODE_X1 = 5,
+ CMPLTSI_OPCODE_Y0 = 4,
+ CMPLTSI_OPCODE_Y1 = 5,
+ CMPLTS_RRR_0_OPCODE_X0 = 10,
+ CMPLTS_RRR_0_OPCODE_X1 = 10,
+ CMPLTS_RRR_2_OPCODE_Y0 = 2,
+ CMPLTS_RRR_2_OPCODE_Y1 = 2,
+ CMPLTUI_IMM8_OPCODE_X0 = 6,
+ CMPLTUI_IMM8_OPCODE_X1 = 6,
+ CMPLTU_RRR_0_OPCODE_X0 = 11,
+ CMPLTU_RRR_0_OPCODE_X1 = 11,
+ CMPLTU_RRR_2_OPCODE_Y0 = 3,
+ CMPLTU_RRR_2_OPCODE_Y1 = 3,
+ CMPNE_RRR_0_OPCODE_X0 = 12,
+ CMPNE_RRR_0_OPCODE_X1 = 12,
+ CMPNE_RRR_3_OPCODE_Y0 = 1,
+ CMPNE_RRR_3_OPCODE_Y1 = 3,
+ CMULAF_RRR_0_OPCODE_X0 = 13,
+ CMULA_RRR_0_OPCODE_X0 = 14,
+ CMULFR_RRR_0_OPCODE_X0 = 15,
+ CMULF_RRR_0_OPCODE_X0 = 16,
+ CMULHR_RRR_0_OPCODE_X0 = 17,
+ CMULH_RRR_0_OPCODE_X0 = 18,
+ CMUL_RRR_0_OPCODE_X0 = 19,
+ CNTLZ_UNARY_OPCODE_X0 = 1,
+ CNTLZ_UNARY_OPCODE_Y0 = 1,
+ CNTTZ_UNARY_OPCODE_X0 = 2,
+ CNTTZ_UNARY_OPCODE_Y0 = 2,
+ CRC32_32_RRR_0_OPCODE_X0 = 20,
+ CRC32_8_RRR_0_OPCODE_X0 = 21,
+ DBLALIGN2_RRR_0_OPCODE_X0 = 22,
+ DBLALIGN2_RRR_0_OPCODE_X1 = 13,
+ DBLALIGN4_RRR_0_OPCODE_X0 = 23,
+ DBLALIGN4_RRR_0_OPCODE_X1 = 14,
+ DBLALIGN6_RRR_0_OPCODE_X0 = 24,
+ DBLALIGN6_RRR_0_OPCODE_X1 = 15,
+ DBLALIGN_RRR_0_OPCODE_X0 = 25,
+ DRAIN_UNARY_OPCODE_X1 = 1,
+ DTLBPR_UNARY_OPCODE_X1 = 2,
+ EXCH4_RRR_0_OPCODE_X1 = 16,
+ EXCH_RRR_0_OPCODE_X1 = 17,
+ FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26,
+ FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27,
+ FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28,
+ FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29,
+ FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30,
+ FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31,
+ FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32,
+ FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33,
+ FETCHADD4_RRR_0_OPCODE_X1 = 18,
+ FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19,
+ FETCHADDGEZ_RRR_0_OPCODE_X1 = 20,
+ FETCHADD_RRR_0_OPCODE_X1 = 21,
+ FETCHAND4_RRR_0_OPCODE_X1 = 22,
+ FETCHAND_RRR_0_OPCODE_X1 = 23,
+ FETCHOR4_RRR_0_OPCODE_X1 = 24,
+ FETCHOR_RRR_0_OPCODE_X1 = 25,
+ FINV_UNARY_OPCODE_X1 = 3,
+ FLUSHWB_UNARY_OPCODE_X1 = 4,
+ FLUSH_UNARY_OPCODE_X1 = 5,
+ FNOP_UNARY_OPCODE_X0 = 3,
+ FNOP_UNARY_OPCODE_X1 = 6,
+ FNOP_UNARY_OPCODE_Y0 = 3,
+ FNOP_UNARY_OPCODE_Y1 = 8,
+ FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34,
+ FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35,
+ FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36,
+ FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37,
+ FSINGLE_PACK1_UNARY_OPCODE_X0 = 4,
+ FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4,
+ FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38,
+ FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39,
+ ICOH_UNARY_OPCODE_X1 = 7,
+ ILL_UNARY_OPCODE_X1 = 8,
+ ILL_UNARY_OPCODE_Y1 = 9,
+ IMM8_OPCODE_X0 = 4,
+ IMM8_OPCODE_X1 = 3,
+ INV_UNARY_OPCODE_X1 = 9,
+ IRET_UNARY_OPCODE_X1 = 10,
+ JALRP_UNARY_OPCODE_X1 = 11,
+ JALRP_UNARY_OPCODE_Y1 = 10,
+ JALR_UNARY_OPCODE_X1 = 12,
+ JALR_UNARY_OPCODE_Y1 = 11,
+ JAL_JUMP_OPCODE_X1 = 0,
+ JRP_UNARY_OPCODE_X1 = 13,
+ JRP_UNARY_OPCODE_Y1 = 12,
+ JR_UNARY_OPCODE_X1 = 14,
+ JR_UNARY_OPCODE_Y1 = 13,
+ JUMP_OPCODE_X1 = 4,
+ J_JUMP_OPCODE_X1 = 1,
+ LD1S_ADD_IMM8_OPCODE_X1 = 7,
+ LD1S_OPCODE_Y2 = 0,
+ LD1S_UNARY_OPCODE_X1 = 15,
+ LD1U_ADD_IMM8_OPCODE_X1 = 8,
+ LD1U_OPCODE_Y2 = 1,
+ LD1U_UNARY_OPCODE_X1 = 16,
+ LD2S_ADD_IMM8_OPCODE_X1 = 9,
+ LD2S_OPCODE_Y2 = 2,
+ LD2S_UNARY_OPCODE_X1 = 17,
+ LD2U_ADD_IMM8_OPCODE_X1 = 10,
+ LD2U_OPCODE_Y2 = 3,
+ LD2U_UNARY_OPCODE_X1 = 18,
+ LD4S_ADD_IMM8_OPCODE_X1 = 11,
+ LD4S_OPCODE_Y2 = 1,
+ LD4S_UNARY_OPCODE_X1 = 19,
+ LD4U_ADD_IMM8_OPCODE_X1 = 12,
+ LD4U_OPCODE_Y2 = 2,
+ LD4U_UNARY_OPCODE_X1 = 20,
+ LDNA_UNARY_OPCODE_X1 = 21,
+ LDNT1S_ADD_IMM8_OPCODE_X1 = 13,
+ LDNT1S_UNARY_OPCODE_X1 = 22,
+ LDNT1U_ADD_IMM8_OPCODE_X1 = 14,
+ LDNT1U_UNARY_OPCODE_X1 = 23,
+ LDNT2S_ADD_IMM8_OPCODE_X1 = 15,
+ LDNT2S_UNARY_OPCODE_X1 = 24,
+ LDNT2U_ADD_IMM8_OPCODE_X1 = 16,
+ LDNT2U_UNARY_OPCODE_X1 = 25,
+ LDNT4S_ADD_IMM8_OPCODE_X1 = 17,
+ LDNT4S_UNARY_OPCODE_X1 = 26,
+ LDNT4U_ADD_IMM8_OPCODE_X1 = 18,
+ LDNT4U_UNARY_OPCODE_X1 = 27,
+ LDNT_ADD_IMM8_OPCODE_X1 = 19,
+ LDNT_UNARY_OPCODE_X1 = 28,
+ LD_ADD_IMM8_OPCODE_X1 = 20,
+ LD_OPCODE_Y2 = 3,
+ LD_UNARY_OPCODE_X1 = 29,
+ LNK_UNARY_OPCODE_X1 = 30,
+ LNK_UNARY_OPCODE_Y1 = 14,
+ LWNA_ADD_IMM8_OPCODE_X1 = 21,
+ MFSPR_IMM8_OPCODE_X1 = 22,
+ MF_UNARY_OPCODE_X1 = 31,
+ MM_BF_OPCODE_X0 = 7,
+ MNZ_RRR_0_OPCODE_X0 = 40,
+ MNZ_RRR_0_OPCODE_X1 = 26,
+ MNZ_RRR_4_OPCODE_Y0 = 2,
+ MNZ_RRR_4_OPCODE_Y1 = 2,
+ MODE_OPCODE_YA2 = 1,
+ MODE_OPCODE_YB2 = 2,
+ MODE_OPCODE_YC2 = 3,
+ MTSPR_IMM8_OPCODE_X1 = 23,
+ MULAX_RRR_0_OPCODE_X0 = 41,
+ MULAX_RRR_3_OPCODE_Y0 = 2,
+ MULA_HS_HS_RRR_0_OPCODE_X0 = 42,
+ MULA_HS_HS_RRR_9_OPCODE_Y0 = 0,
+ MULA_HS_HU_RRR_0_OPCODE_X0 = 43,
+ MULA_HS_LS_RRR_0_OPCODE_X0 = 44,
+ MULA_HS_LU_RRR_0_OPCODE_X0 = 45,
+ MULA_HU_HU_RRR_0_OPCODE_X0 = 46,
+ MULA_HU_HU_RRR_9_OPCODE_Y0 = 1,
+ MULA_HU_LS_RRR_0_OPCODE_X0 = 47,
+ MULA_HU_LU_RRR_0_OPCODE_X0 = 48,
+ MULA_LS_LS_RRR_0_OPCODE_X0 = 49,
+ MULA_LS_LS_RRR_9_OPCODE_Y0 = 2,
+ MULA_LS_LU_RRR_0_OPCODE_X0 = 50,
+ MULA_LU_LU_RRR_0_OPCODE_X0 = 51,
+ MULA_LU_LU_RRR_9_OPCODE_Y0 = 3,
+ MULX_RRR_0_OPCODE_X0 = 52,
+ MULX_RRR_3_OPCODE_Y0 = 3,
+ MUL_HS_HS_RRR_0_OPCODE_X0 = 53,
+ MUL_HS_HS_RRR_8_OPCODE_Y0 = 0,
+ MUL_HS_HU_RRR_0_OPCODE_X0 = 54,
+ MUL_HS_LS_RRR_0_OPCODE_X0 = 55,
+ MUL_HS_LU_RRR_0_OPCODE_X0 = 56,
+ MUL_HU_HU_RRR_0_OPCODE_X0 = 57,
+ MUL_HU_HU_RRR_8_OPCODE_Y0 = 1,
+ MUL_HU_LS_RRR_0_OPCODE_X0 = 58,
+ MUL_HU_LU_RRR_0_OPCODE_X0 = 59,
+ MUL_LS_LS_RRR_0_OPCODE_X0 = 60,
+ MUL_LS_LS_RRR_8_OPCODE_Y0 = 2,
+ MUL_LS_LU_RRR_0_OPCODE_X0 = 61,
+ MUL_LU_LU_RRR_0_OPCODE_X0 = 62,
+ MUL_LU_LU_RRR_8_OPCODE_Y0 = 3,
+ MZ_RRR_0_OPCODE_X0 = 63,
+ MZ_RRR_0_OPCODE_X1 = 27,
+ MZ_RRR_4_OPCODE_Y0 = 3,
+ MZ_RRR_4_OPCODE_Y1 = 3,
+ NAP_UNARY_OPCODE_X1 = 32,
+ NOP_UNARY_OPCODE_X0 = 5,
+ NOP_UNARY_OPCODE_X1 = 33,
+ NOP_UNARY_OPCODE_Y0 = 5,
+ NOP_UNARY_OPCODE_Y1 = 15,
+ NOR_RRR_0_OPCODE_X0 = 64,
+ NOR_RRR_0_OPCODE_X1 = 28,
+ NOR_RRR_5_OPCODE_Y0 = 1,
+ NOR_RRR_5_OPCODE_Y1 = 1,
+ ORI_IMM8_OPCODE_X0 = 7,
+ ORI_IMM8_OPCODE_X1 = 24,
+ OR_RRR_0_OPCODE_X0 = 65,
+ OR_RRR_0_OPCODE_X1 = 29,
+ OR_RRR_5_OPCODE_Y0 = 2,
+ OR_RRR_5_OPCODE_Y1 = 2,
+ PCNT_UNARY_OPCODE_X0 = 6,
+ PCNT_UNARY_OPCODE_Y0 = 6,
+ REVBITS_UNARY_OPCODE_X0 = 7,
+ REVBITS_UNARY_OPCODE_Y0 = 7,
+ REVBYTES_UNARY_OPCODE_X0 = 8,
+ REVBYTES_UNARY_OPCODE_Y0 = 8,
+ ROTLI_SHIFT_OPCODE_X0 = 1,
+ ROTLI_SHIFT_OPCODE_X1 = 1,
+ ROTLI_SHIFT_OPCODE_Y0 = 0,
+ ROTLI_SHIFT_OPCODE_Y1 = 0,
+ ROTL_RRR_0_OPCODE_X0 = 66,
+ ROTL_RRR_0_OPCODE_X1 = 30,
+ ROTL_RRR_6_OPCODE_Y0 = 0,
+ ROTL_RRR_6_OPCODE_Y1 = 0,
+ RRR_0_OPCODE_X0 = 5,
+ RRR_0_OPCODE_X1 = 5,
+ RRR_0_OPCODE_Y0 = 5,
+ RRR_0_OPCODE_Y1 = 6,
+ RRR_1_OPCODE_Y0 = 6,
+ RRR_1_OPCODE_Y1 = 7,
+ RRR_2_OPCODE_Y0 = 7,
+ RRR_2_OPCODE_Y1 = 8,
+ RRR_3_OPCODE_Y0 = 8,
+ RRR_3_OPCODE_Y1 = 9,
+ RRR_4_OPCODE_Y0 = 9,
+ RRR_4_OPCODE_Y1 = 10,
+ RRR_5_OPCODE_Y0 = 10,
+ RRR_5_OPCODE_Y1 = 11,
+ RRR_6_OPCODE_Y0 = 11,
+ RRR_6_OPCODE_Y1 = 12,
+ RRR_7_OPCODE_Y0 = 12,
+ RRR_7_OPCODE_Y1 = 13,
+ RRR_8_OPCODE_Y0 = 13,
+ RRR_9_OPCODE_Y0 = 14,
+ SHIFT_OPCODE_X0 = 6,
+ SHIFT_OPCODE_X1 = 6,
+ SHIFT_OPCODE_Y0 = 15,
+ SHIFT_OPCODE_Y1 = 14,
+ SHL16INSLI_OPCODE_X0 = 7,
+ SHL16INSLI_OPCODE_X1 = 7,
+ SHL1ADDX_RRR_0_OPCODE_X0 = 67,
+ SHL1ADDX_RRR_0_OPCODE_X1 = 31,
+ SHL1ADDX_RRR_7_OPCODE_Y0 = 1,
+ SHL1ADDX_RRR_7_OPCODE_Y1 = 1,
+ SHL1ADD_RRR_0_OPCODE_X0 = 68,
+ SHL1ADD_RRR_0_OPCODE_X1 = 32,
+ SHL1ADD_RRR_1_OPCODE_Y0 = 0,
+ SHL1ADD_RRR_1_OPCODE_Y1 = 0,
+ SHL2ADDX_RRR_0_OPCODE_X0 = 69,
+ SHL2ADDX_RRR_0_OPCODE_X1 = 33,
+ SHL2ADDX_RRR_7_OPCODE_Y0 = 2,
+ SHL2ADDX_RRR_7_OPCODE_Y1 = 2,
+ SHL2ADD_RRR_0_OPCODE_X0 = 70,
+ SHL2ADD_RRR_0_OPCODE_X1 = 34,
+ SHL2ADD_RRR_1_OPCODE_Y0 = 1,
+ SHL2ADD_RRR_1_OPCODE_Y1 = 1,
+ SHL3ADDX_RRR_0_OPCODE_X0 = 71,
+ SHL3ADDX_RRR_0_OPCODE_X1 = 35,
+ SHL3ADDX_RRR_7_OPCODE_Y0 = 3,
+ SHL3ADDX_RRR_7_OPCODE_Y1 = 3,
+ SHL3ADD_RRR_0_OPCODE_X0 = 72,
+ SHL3ADD_RRR_0_OPCODE_X1 = 36,
+ SHL3ADD_RRR_1_OPCODE_Y0 = 2,
+ SHL3ADD_RRR_1_OPCODE_Y1 = 2,
+ SHLI_SHIFT_OPCODE_X0 = 2,
+ SHLI_SHIFT_OPCODE_X1 = 2,
+ SHLI_SHIFT_OPCODE_Y0 = 1,
+ SHLI_SHIFT_OPCODE_Y1 = 1,
+ SHLXI_SHIFT_OPCODE_X0 = 3,
+ SHLXI_SHIFT_OPCODE_X1 = 3,
+ SHLX_RRR_0_OPCODE_X0 = 73,
+ SHLX_RRR_0_OPCODE_X1 = 37,
+ SHL_RRR_0_OPCODE_X0 = 74,
+ SHL_RRR_0_OPCODE_X1 = 38,
+ SHL_RRR_6_OPCODE_Y0 = 1,
+ SHL_RRR_6_OPCODE_Y1 = 1,
+ SHRSI_SHIFT_OPCODE_X0 = 4,
+ SHRSI_SHIFT_OPCODE_X1 = 4,
+ SHRSI_SHIFT_OPCODE_Y0 = 2,
+ SHRSI_SHIFT_OPCODE_Y1 = 2,
+ SHRS_RRR_0_OPCODE_X0 = 75,
+ SHRS_RRR_0_OPCODE_X1 = 39,
+ SHRS_RRR_6_OPCODE_Y0 = 2,
+ SHRS_RRR_6_OPCODE_Y1 = 2,
+ SHRUI_SHIFT_OPCODE_X0 = 5,
+ SHRUI_SHIFT_OPCODE_X1 = 5,
+ SHRUI_SHIFT_OPCODE_Y0 = 3,
+ SHRUI_SHIFT_OPCODE_Y1 = 3,
+ SHRUXI_SHIFT_OPCODE_X0 = 6,
+ SHRUXI_SHIFT_OPCODE_X1 = 6,
+ SHRUX_RRR_0_OPCODE_X0 = 76,
+ SHRUX_RRR_0_OPCODE_X1 = 40,
+ SHRU_RRR_0_OPCODE_X0 = 77,
+ SHRU_RRR_0_OPCODE_X1 = 41,
+ SHRU_RRR_6_OPCODE_Y0 = 3,
+ SHRU_RRR_6_OPCODE_Y1 = 3,
+ SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78,
+ ST1_ADD_IMM8_OPCODE_X1 = 25,
+ ST1_OPCODE_Y2 = 0,
+ ST1_RRR_0_OPCODE_X1 = 42,
+ ST2_ADD_IMM8_OPCODE_X1 = 26,
+ ST2_OPCODE_Y2 = 1,
+ ST2_RRR_0_OPCODE_X1 = 43,
+ ST4_ADD_IMM8_OPCODE_X1 = 27,
+ ST4_OPCODE_Y2 = 2,
+ ST4_RRR_0_OPCODE_X1 = 44,
+ STNT1_ADD_IMM8_OPCODE_X1 = 28,
+ STNT1_RRR_0_OPCODE_X1 = 45,
+ STNT2_ADD_IMM8_OPCODE_X1 = 29,
+ STNT2_RRR_0_OPCODE_X1 = 46,
+ STNT4_ADD_IMM8_OPCODE_X1 = 30,
+ STNT4_RRR_0_OPCODE_X1 = 47,
+ STNT_ADD_IMM8_OPCODE_X1 = 31,
+ STNT_RRR_0_OPCODE_X1 = 48,
+ ST_ADD_IMM8_OPCODE_X1 = 32,
+ ST_OPCODE_Y2 = 3,
+ ST_RRR_0_OPCODE_X1 = 49,
+ SUBXSC_RRR_0_OPCODE_X0 = 79,
+ SUBXSC_RRR_0_OPCODE_X1 = 50,
+ SUBX_RRR_0_OPCODE_X0 = 80,
+ SUBX_RRR_0_OPCODE_X1 = 51,
+ SUBX_RRR_0_OPCODE_Y0 = 2,
+ SUBX_RRR_0_OPCODE_Y1 = 2,
+ SUB_RRR_0_OPCODE_X0 = 81,
+ SUB_RRR_0_OPCODE_X1 = 52,
+ SUB_RRR_0_OPCODE_Y0 = 3,
+ SUB_RRR_0_OPCODE_Y1 = 3,
+ SWINT0_UNARY_OPCODE_X1 = 34,
+ SWINT1_UNARY_OPCODE_X1 = 35,
+ SWINT2_UNARY_OPCODE_X1 = 36,
+ SWINT3_UNARY_OPCODE_X1 = 37,
+ TBLIDXB0_UNARY_OPCODE_X0 = 9,
+ TBLIDXB0_UNARY_OPCODE_Y0 = 9,
+ TBLIDXB1_UNARY_OPCODE_X0 = 10,
+ TBLIDXB1_UNARY_OPCODE_Y0 = 10,
+ TBLIDXB2_UNARY_OPCODE_X0 = 11,
+ TBLIDXB2_UNARY_OPCODE_Y0 = 11,
+ TBLIDXB3_UNARY_OPCODE_X0 = 12,
+ TBLIDXB3_UNARY_OPCODE_Y0 = 12,
+ UNARY_RRR_0_OPCODE_X0 = 82,
+ UNARY_RRR_0_OPCODE_X1 = 53,
+ UNARY_RRR_1_OPCODE_Y0 = 3,
+ UNARY_RRR_1_OPCODE_Y1 = 3,
+ V1ADDI_IMM8_OPCODE_X0 = 8,
+ V1ADDI_IMM8_OPCODE_X1 = 33,
+ V1ADDUC_RRR_0_OPCODE_X0 = 83,
+ V1ADDUC_RRR_0_OPCODE_X1 = 54,
+ V1ADD_RRR_0_OPCODE_X0 = 84,
+ V1ADD_RRR_0_OPCODE_X1 = 55,
+ V1ADIFFU_RRR_0_OPCODE_X0 = 85,
+ V1AVGU_RRR_0_OPCODE_X0 = 86,
+ V1CMPEQI_IMM8_OPCODE_X0 = 9,
+ V1CMPEQI_IMM8_OPCODE_X1 = 34,
+ V1CMPEQ_RRR_0_OPCODE_X0 = 87,
+ V1CMPEQ_RRR_0_OPCODE_X1 = 56,
+ V1CMPLES_RRR_0_OPCODE_X0 = 88,
+ V1CMPLES_RRR_0_OPCODE_X1 = 57,
+ V1CMPLEU_RRR_0_OPCODE_X0 = 89,
+ V1CMPLEU_RRR_0_OPCODE_X1 = 58,
+ V1CMPLTSI_IMM8_OPCODE_X0 = 10,
+ V1CMPLTSI_IMM8_OPCODE_X1 = 35,
+ V1CMPLTS_RRR_0_OPCODE_X0 = 90,
+ V1CMPLTS_RRR_0_OPCODE_X1 = 59,
+ V1CMPLTUI_IMM8_OPCODE_X0 = 11,
+ V1CMPLTUI_IMM8_OPCODE_X1 = 36,
+ V1CMPLTU_RRR_0_OPCODE_X0 = 91,
+ V1CMPLTU_RRR_0_OPCODE_X1 = 60,
+ V1CMPNE_RRR_0_OPCODE_X0 = 92,
+ V1CMPNE_RRR_0_OPCODE_X1 = 61,
+ V1DDOTPUA_RRR_0_OPCODE_X0 = 161,
+ V1DDOTPUSA_RRR_0_OPCODE_X0 = 93,
+ V1DDOTPUS_RRR_0_OPCODE_X0 = 94,
+ V1DDOTPU_RRR_0_OPCODE_X0 = 162,
+ V1DOTPA_RRR_0_OPCODE_X0 = 95,
+ V1DOTPUA_RRR_0_OPCODE_X0 = 163,
+ V1DOTPUSA_RRR_0_OPCODE_X0 = 96,
+ V1DOTPUS_RRR_0_OPCODE_X0 = 97,
+ V1DOTPU_RRR_0_OPCODE_X0 = 164,
+ V1DOTP_RRR_0_OPCODE_X0 = 98,
+ V1INT_H_RRR_0_OPCODE_X0 = 99,
+ V1INT_H_RRR_0_OPCODE_X1 = 62,
+ V1INT_L_RRR_0_OPCODE_X0 = 100,
+ V1INT_L_RRR_0_OPCODE_X1 = 63,
+ V1MAXUI_IMM8_OPCODE_X0 = 12,
+ V1MAXUI_IMM8_OPCODE_X1 = 37,
+ V1MAXU_RRR_0_OPCODE_X0 = 101,
+ V1MAXU_RRR_0_OPCODE_X1 = 64,
+ V1MINUI_IMM8_OPCODE_X0 = 13,
+ V1MINUI_IMM8_OPCODE_X1 = 38,
+ V1MINU_RRR_0_OPCODE_X0 = 102,
+ V1MINU_RRR_0_OPCODE_X1 = 65,
+ V1MNZ_RRR_0_OPCODE_X0 = 103,
+ V1MNZ_RRR_0_OPCODE_X1 = 66,
+ V1MULTU_RRR_0_OPCODE_X0 = 104,
+ V1MULUS_RRR_0_OPCODE_X0 = 105,
+ V1MULU_RRR_0_OPCODE_X0 = 106,
+ V1MZ_RRR_0_OPCODE_X0 = 107,
+ V1MZ_RRR_0_OPCODE_X1 = 67,
+ V1SADAU_RRR_0_OPCODE_X0 = 108,
+ V1SADU_RRR_0_OPCODE_X0 = 109,
+ V1SHLI_SHIFT_OPCODE_X0 = 7,
+ V1SHLI_SHIFT_OPCODE_X1 = 7,
+ V1SHL_RRR_0_OPCODE_X0 = 110,
+ V1SHL_RRR_0_OPCODE_X1 = 68,
+ V1SHRSI_SHIFT_OPCODE_X0 = 8,
+ V1SHRSI_SHIFT_OPCODE_X1 = 8,
+ V1SHRS_RRR_0_OPCODE_X0 = 111,
+ V1SHRS_RRR_0_OPCODE_X1 = 69,
+ V1SHRUI_SHIFT_OPCODE_X0 = 9,
+ V1SHRUI_SHIFT_OPCODE_X1 = 9,
+ V1SHRU_RRR_0_OPCODE_X0 = 112,
+ V1SHRU_RRR_0_OPCODE_X1 = 70,
+ V1SUBUC_RRR_0_OPCODE_X0 = 113,
+ V1SUBUC_RRR_0_OPCODE_X1 = 71,
+ V1SUB_RRR_0_OPCODE_X0 = 114,
+ V1SUB_RRR_0_OPCODE_X1 = 72,
+ V2ADDI_IMM8_OPCODE_X0 = 14,
+ V2ADDI_IMM8_OPCODE_X1 = 39,
+ V2ADDSC_RRR_0_OPCODE_X0 = 115,
+ V2ADDSC_RRR_0_OPCODE_X1 = 73,
+ V2ADD_RRR_0_OPCODE_X0 = 116,
+ V2ADD_RRR_0_OPCODE_X1 = 74,
+ V2ADIFFS_RRR_0_OPCODE_X0 = 117,
+ V2AVGS_RRR_0_OPCODE_X0 = 118,
+ V2CMPEQI_IMM8_OPCODE_X0 = 15,
+ V2CMPEQI_IMM8_OPCODE_X1 = 40,
+ V2CMPEQ_RRR_0_OPCODE_X0 = 119,
+ V2CMPEQ_RRR_0_OPCODE_X1 = 75,
+ V2CMPLES_RRR_0_OPCODE_X0 = 120,
+ V2CMPLES_RRR_0_OPCODE_X1 = 76,
+ V2CMPLEU_RRR_0_OPCODE_X0 = 121,
+ V2CMPLEU_RRR_0_OPCODE_X1 = 77,
+ V2CMPLTSI_IMM8_OPCODE_X0 = 16,
+ V2CMPLTSI_IMM8_OPCODE_X1 = 41,
+ V2CMPLTS_RRR_0_OPCODE_X0 = 122,
+ V2CMPLTS_RRR_0_OPCODE_X1 = 78,
+ V2CMPLTUI_IMM8_OPCODE_X0 = 17,
+ V2CMPLTUI_IMM8_OPCODE_X1 = 42,
+ V2CMPLTU_RRR_0_OPCODE_X0 = 123,
+ V2CMPLTU_RRR_0_OPCODE_X1 = 79,
+ V2CMPNE_RRR_0_OPCODE_X0 = 124,
+ V2CMPNE_RRR_0_OPCODE_X1 = 80,
+ V2DOTPA_RRR_0_OPCODE_X0 = 125,
+ V2DOTP_RRR_0_OPCODE_X0 = 126,
+ V2INT_H_RRR_0_OPCODE_X0 = 127,
+ V2INT_H_RRR_0_OPCODE_X1 = 81,
+ V2INT_L_RRR_0_OPCODE_X0 = 128,
+ V2INT_L_RRR_0_OPCODE_X1 = 82,
+ V2MAXSI_IMM8_OPCODE_X0 = 18,
+ V2MAXSI_IMM8_OPCODE_X1 = 43,
+ V2MAXS_RRR_0_OPCODE_X0 = 129,
+ V2MAXS_RRR_0_OPCODE_X1 = 83,
+ V2MINSI_IMM8_OPCODE_X0 = 19,
+ V2MINSI_IMM8_OPCODE_X1 = 44,
+ V2MINS_RRR_0_OPCODE_X0 = 130,
+ V2MINS_RRR_0_OPCODE_X1 = 84,
+ V2MNZ_RRR_0_OPCODE_X0 = 131,
+ V2MNZ_RRR_0_OPCODE_X1 = 85,
+ V2MULFSC_RRR_0_OPCODE_X0 = 132,
+ V2MULS_RRR_0_OPCODE_X0 = 133,
+ V2MULTS_RRR_0_OPCODE_X0 = 134,
+ V2MZ_RRR_0_OPCODE_X0 = 135,
+ V2MZ_RRR_0_OPCODE_X1 = 86,
+ V2PACKH_RRR_0_OPCODE_X0 = 136,
+ V2PACKH_RRR_0_OPCODE_X1 = 87,
+ V2PACKL_RRR_0_OPCODE_X0 = 137,
+ V2PACKL_RRR_0_OPCODE_X1 = 88,
+ V2PACKUC_RRR_0_OPCODE_X0 = 138,
+ V2PACKUC_RRR_0_OPCODE_X1 = 89,
+ V2SADAS_RRR_0_OPCODE_X0 = 139,
+ V2SADAU_RRR_0_OPCODE_X0 = 140,
+ V2SADS_RRR_0_OPCODE_X0 = 141,
+ V2SADU_RRR_0_OPCODE_X0 = 142,
+ V2SHLI_SHIFT_OPCODE_X0 = 10,
+ V2SHLI_SHIFT_OPCODE_X1 = 10,
+ V2SHLSC_RRR_0_OPCODE_X0 = 143,
+ V2SHLSC_RRR_0_OPCODE_X1 = 90,
+ V2SHL_RRR_0_OPCODE_X0 = 144,
+ V2SHL_RRR_0_OPCODE_X1 = 91,
+ V2SHRSI_SHIFT_OPCODE_X0 = 11,
+ V2SHRSI_SHIFT_OPCODE_X1 = 11,
+ V2SHRS_RRR_0_OPCODE_X0 = 145,
+ V2SHRS_RRR_0_OPCODE_X1 = 92,
+ V2SHRUI_SHIFT_OPCODE_X0 = 12,
+ V2SHRUI_SHIFT_OPCODE_X1 = 12,
+ V2SHRU_RRR_0_OPCODE_X0 = 146,
+ V2SHRU_RRR_0_OPCODE_X1 = 93,
+ V2SUBSC_RRR_0_OPCODE_X0 = 147,
+ V2SUBSC_RRR_0_OPCODE_X1 = 94,
+ V2SUB_RRR_0_OPCODE_X0 = 148,
+ V2SUB_RRR_0_OPCODE_X1 = 95,
+ V4ADDSC_RRR_0_OPCODE_X0 = 149,
+ V4ADDSC_RRR_0_OPCODE_X1 = 96,
+ V4ADD_RRR_0_OPCODE_X0 = 150,
+ V4ADD_RRR_0_OPCODE_X1 = 97,
+ V4INT_H_RRR_0_OPCODE_X0 = 151,
+ V4INT_H_RRR_0_OPCODE_X1 = 98,
+ V4INT_L_RRR_0_OPCODE_X0 = 152,
+ V4INT_L_RRR_0_OPCODE_X1 = 99,
+ V4PACKSC_RRR_0_OPCODE_X0 = 153,
+ V4PACKSC_RRR_0_OPCODE_X1 = 100,
+ V4SHLSC_RRR_0_OPCODE_X0 = 154,
+ V4SHLSC_RRR_0_OPCODE_X1 = 101,
+ V4SHL_RRR_0_OPCODE_X0 = 155,
+ V4SHL_RRR_0_OPCODE_X1 = 102,
+ V4SHRS_RRR_0_OPCODE_X0 = 156,
+ V4SHRS_RRR_0_OPCODE_X1 = 103,
+ V4SHRU_RRR_0_OPCODE_X0 = 157,
+ V4SHRU_RRR_0_OPCODE_X1 = 104,
+ V4SUBSC_RRR_0_OPCODE_X0 = 158,
+ V4SUBSC_RRR_0_OPCODE_X1 = 105,
+ V4SUB_RRR_0_OPCODE_X0 = 159,
+ V4SUB_RRR_0_OPCODE_X1 = 106,
+ WH64_UNARY_OPCODE_X1 = 38,
+ XORI_IMM8_OPCODE_X0 = 20,
+ XORI_IMM8_OPCODE_X1 = 45,
+ XOR_RRR_0_OPCODE_X0 = 160,
+ XOR_RRR_0_OPCODE_X1 = 107,
+ XOR_RRR_5_OPCODE_Y0 = 3,
+ XOR_RRR_5_OPCODE_Y1 = 3
+};
+
+static __inline unsigned int
+get_BFEnd_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 24)) & 0xf);
+}
+
+static __inline unsigned int
+get_BFStart_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x3f);
+}
+
+static __inline unsigned int
+get_BrOff_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x0000003f) |
+ (((unsigned int)(n >> 37)) & 0x0001ffc0);
+}
+
+static __inline unsigned int
+get_BrType_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 54)) & 0x1f);
+}
+
+static __inline unsigned int
+get_Dest_Imm8_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x0000003f) |
+ (((unsigned int)(n >> 43)) & 0x000000c0);
+}
+
+static __inline unsigned int
+get_Dest_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Imm16_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm16_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 20)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 51)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_JumpOff_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x7ffffff);
+}
+
+static __inline unsigned int
+get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 58)) & 0x1);
+}
+
+static __inline unsigned int
+get_MF_Imm14_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x3fff);
+}
+
+static __inline unsigned int
+get_MT_Imm14_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x0000003f) |
+ (((unsigned int)(n >> 37)) & 0x00003fc0);
+}
+
+static __inline unsigned int
+get_Mode(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 62)) & 0x3);
+}
+
+static __inline unsigned int
+get_Opcode_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 28)) & 0x7);
+}
+
+static __inline unsigned int
+get_Opcode_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 59)) & 0x7);
+}
+
+static __inline unsigned int
+get_Opcode_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 27)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 58)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y2(tilegx_bundle_bits n)
+{
+ return (((n >> 26)) & 0x00000001) |
+ (((unsigned int)(n >> 56)) & 0x00000002);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x3);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x3);
+}
+
+static __inline unsigned int
+get_ShAmt_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShAmt_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x3);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x3);
+}
+
+static __inline unsigned int
+get_SrcA_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y2(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 20)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcBDest_Y2(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 51)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline int
+sign_extend(int n, int num_bits)
+{
+ int shift = (int)(sizeof(int) * 8 - num_bits);
+ return (n << shift) >> shift;
+}
+
+static __inline tilegx_bundle_bits
+create_BFEnd_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_BFOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 24);
+}
+
+static __inline tilegx_bundle_bits
+create_BFStart_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_BrOff_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+ (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_BrType_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_Imm8_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+ (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 0);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 0);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm16_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xffff) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm16_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8OpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 20);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8OpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0xff)) << 51);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_JumpOff_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
+}
+
+static __inline tilegx_bundle_bits
+create_JumpOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x1)) << 58);
+}
+
+static __inline tilegx_bundle_bits
+create_MF_Imm14_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_MT_Imm14_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+ (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_Mode(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3)) << 62);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x7) << 28);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x7)) << 59);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 27);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0xf)) << 58);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x00000001) << 26) |
+ (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 6);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 6);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 20);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcBDest_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+const struct tilegx_opcode tilegx_opcodes[336] =
+{
+ { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffffffff80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a44ae00000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
+ { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00fffULL,
+ 0xfff807ff80000000ULL,
+ 0x0000000078000fffULL,
+ 0x3c0007ff80000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040300fffULL,
+ 0x181807ff80000000ULL,
+ 0x0000000010000fffULL,
+ 0x0c0007ff80000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
+ { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc000000070000fffULL,
+ 0xf80007ff80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000070000fffULL,
+ 0x380007ff80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1858000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18a0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
+ { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0xfffff80000000000ULL,
+ 0x00000000780ff000ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ 0x000000005107f000ULL,
+ 0x283bf80000000000ULL,
+ 0x00000000500bf000ULL,
+ 0x2c05f80000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
+ { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00fc0ULL,
+ 0xfff807e000000000ULL,
+ 0x0000000078000fc0ULL,
+ 0x3c0007e000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040100fc0ULL,
+ 0x180807e000000000ULL,
+ 0x0000000000000fc0ULL,
+ 0x040007e000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
+ { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc000000070000fc0ULL,
+ 0xf80007e000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000010000fc0ULL,
+ 0x000007e000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff81f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc3f8000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a801f80000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x41f8000004000000ULL
+ }
+#endif
+ },
+ { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8001f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1840001f80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8001f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1838001f80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8001f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1850001f80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8001f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1848001f80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8001f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1860001f80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8001f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1858001f80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff81f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc3f8000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a801f80000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x41f8000004000000ULL
+ }
+#endif
+ },
+ { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff81f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc3f8000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a781f80000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x41f8000000000000ULL
+ }
+#endif
+ },
+ { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff81f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc3f8000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a901f80000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x43f8000004000000ULL
+ }
+#endif
+ },
+ { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff81f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc3f8000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a881f80000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x43f8000000000000ULL
+ }
+#endif
+ },
+ { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff81f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc3f8000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286aa01f80000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x83f8000000000000ULL
+ }
+#endif
+ },
+ { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff81f80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc3f8000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a981f80000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x81f8000004000000ULL
+ }
+#endif
+ },
+ { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffffffff80000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a44ae80000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x00000000500c0000ULL,
+ 0x2806000000000000ULL,
+ 0x0000000028040000ULL,
+ 0x1802000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0x0000000078000000ULL,
+ 0x3c00000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040100000ULL,
+ 0x1808000000000000ULL,
+ 0ULL,
+ 0x0400000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc000000070000000ULL,
+ 0xf800000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000010000000ULL,
+ 0ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050080000ULL,
+ 0x2804000000000000ULL,
+ 0x0000000028000000ULL,
+ 0x1800000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0x0000000078000000ULL,
+ 0x3c00000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040200000ULL,
+ 0x1810000000000000ULL,
+ 0x0000000008000000ULL,
+ 0x0800000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc000000070000000ULL,
+ 0xf800000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000020000000ULL,
+ 0x0800000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050040000ULL,
+ 0x2802000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050100000ULL,
+ 0x2808000000000000ULL,
+ 0x0000000050000000ULL,
+ 0x2c00000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0x0000000078000000ULL,
+ 0x3c00000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040300000ULL,
+ 0x1818000000000000ULL,
+ 0x0000000010000000ULL,
+ 0x0c00000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1440000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1400000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1,
+ { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007f000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000034000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1,
+ { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007f000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000035000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1,
+ { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007f000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000036000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x14c0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1480000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1540000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1500000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x15c0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1580000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1640000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1600000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x16c0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1680000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1740000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1700000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x17c0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xffc0000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1780000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
+ { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051481000ULL,
+ -1ULL,
+ 0x00000000300c1000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050140000ULL,
+ -1ULL,
+ 0x0000000048000000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050180000ULL,
+ -1ULL,
+ 0x0000000048040000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x00000000501c0000ULL,
+ 0x280a000000000000ULL,
+ 0x0000000040000000ULL,
+ 0x2404000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0x0000000078000000ULL,
+ 0x3c00000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040400000ULL,
+ 0x1820000000000000ULL,
+ 0x0000000018000000ULL,
+ 0x1000000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x280e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x280c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050200000ULL,
+ 0x2810000000000000ULL,
+ 0x0000000038000000ULL,
+ 0x2000000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050240000ULL,
+ 0x2812000000000000ULL,
+ 0x0000000038040000ULL,
+ 0x2002000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050280000ULL,
+ 0x2814000000000000ULL,
+ 0x0000000038080000ULL,
+ 0x2004000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0x0000000078000000ULL,
+ 0x3c00000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040500000ULL,
+ 0x1828000000000000ULL,
+ 0x0000000020000000ULL,
+ 0x1400000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x00000000502c0000ULL,
+ 0x2816000000000000ULL,
+ 0x00000000380c0000ULL,
+ 0x2006000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040600000ULL,
+ 0x1830000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050300000ULL,
+ 0x2818000000000000ULL,
+ 0x0000000040040000ULL,
+ 0x2406000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000504c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050380000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050340000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050400000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000503c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050480000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050440000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050500000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050540000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
+ { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051482000ULL,
+ -1ULL,
+ 0x00000000300c2000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050640000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050580000ULL,
+ 0x281a000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000505c0000ULL,
+ 0x281c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050600000ULL,
+ 0x281e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a080000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a100000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2822000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2820000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000506c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050680000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050700000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050740000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050780000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000507c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050800000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050840000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x282a000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2824000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2828000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2826000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x282e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x282c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2832000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2830000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a180000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a280000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a200000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
+ { { }, { }, { }, { }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0xfffff80000000000ULL,
+ 0x00000000780ff000ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051483000ULL,
+ 0x286a300000000000ULL,
+ 0x00000000300c3000ULL,
+ 0x1c06400000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050880000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000508c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050900000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050940000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1,
+ { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051484000ULL,
+ -1ULL,
+ 0x00000000300c4000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050980000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000509c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a380000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a400000000000ULL,
+ -1ULL,
+ 0x1c06480000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a480000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a500000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfc00000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2400000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1,
+ { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfc00000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2000000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1,
+ { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a600000000000ULL,
+ -1ULL,
+ 0x1c06580000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1,
+ { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a580000000000ULL,
+ -1ULL,
+ 0x1c06500000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a700000000000ULL,
+ -1ULL,
+ 0x1c06680000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286a680000000000ULL,
+ -1ULL,
+ 0x1c06600000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286ae80000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x8200000004000000ULL
+ }
+#endif
+ },
+ { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a780000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x4000000000000000ULL
+ }
+#endif
+ },
+ { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1838000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a800000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x4000000004000000ULL
+ }
+#endif
+ },
+ { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1840000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a880000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x4200000000000000ULL
+ }
+#endif
+ },
+ { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1848000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a900000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x4200000004000000ULL
+ }
+#endif
+ },
+ { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1850000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286a980000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x8000000004000000ULL
+ }
+#endif
+ },
+ { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1858000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x286aa00000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0x8200000000000000ULL
+ }
+#endif
+ },
+ { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1860000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18a0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286aa80000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18a8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286ae00000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286ab00000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1868000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286ab80000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1870000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286ac00000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1878000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286ac80000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1880000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286ad00000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1888000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286ad80000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1890000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1898000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1,
+ { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286af00000000000ULL,
+ -1ULL,
+ 0x1c06700000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286af80000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18b0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1,
+ { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007f000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000037000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050a00000ULL,
+ 0x2834000000000000ULL,
+ 0x0000000048080000ULL,
+ 0x2804000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18b8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050d40000ULL,
+ -1ULL,
+ 0x0000000068000000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050d80000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050dc0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050e00000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050e40000ULL,
+ -1ULL,
+ 0x0000000068040000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050e80000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050ec0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050f00000ULL,
+ -1ULL,
+ 0x0000000068080000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050f40000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050f80000ULL,
+ -1ULL,
+ 0x00000000680c0000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050a80000ULL,
+ -1ULL,
+ 0x0000000070000000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050ac0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050b00000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050b40000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050b80000ULL,
+ -1ULL,
+ 0x0000000070040000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050bc0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050c00000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050c40000ULL,
+ -1ULL,
+ 0x0000000070080000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050c80000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050cc0000ULL,
+ -1ULL,
+ 0x00000000700c0000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050a40000ULL,
+ -1ULL,
+ 0x0000000040080000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0x00000000780c0000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050d00000ULL,
+ -1ULL,
+ 0x00000000400c0000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000050fc0000ULL,
+ 0x2836000000000000ULL,
+ 0x00000000480c0000ULL,
+ 0x2806000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286b000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
+ { { }, { }, { }, { }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0xfffff80000000000ULL,
+ 0x00000000780ff000ULL,
+ 0x3c07f80000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051485000ULL,
+ 0x286b080000000000ULL,
+ 0x00000000300c5000ULL,
+ 0x1c06780000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051000000ULL,
+ 0x2838000000000000ULL,
+ 0x0000000050040000ULL,
+ 0x2c02000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051040000ULL,
+ 0x283a000000000000ULL,
+ 0x0000000050080000ULL,
+ 0x2c04000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040700000ULL,
+ 0x18c0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
+ { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051486000ULL,
+ -1ULL,
+ 0x00000000300c6000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1,
+ { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051487000ULL,
+ -1ULL,
+ 0x00000000300c7000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1,
+ { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051488000ULL,
+ -1ULL,
+ 0x00000000300c8000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051080000ULL,
+ 0x283c000000000000ULL,
+ 0x0000000058000000ULL,
+ 0x3000000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060040000ULL,
+ 0x3002000000000000ULL,
+ 0x0000000078000000ULL,
+ 0x3800000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051280000ULL,
+ 0x284c000000000000ULL,
+ 0x0000000058040000ULL,
+ 0x3002000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc000000070000000ULL,
+ 0xf800000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000070000000ULL,
+ 0x3800000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051100000ULL,
+ 0x2840000000000000ULL,
+ 0x0000000030000000ULL,
+ 0x1c00000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x00000000510c0000ULL,
+ 0x283e000000000000ULL,
+ 0x0000000060040000ULL,
+ 0x3402000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051180000ULL,
+ 0x2844000000000000ULL,
+ 0x0000000030040000ULL,
+ 0x1c02000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051140000ULL,
+ 0x2842000000000000ULL,
+ 0x0000000060080000ULL,
+ 0x3404000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051200000ULL,
+ 0x2848000000000000ULL,
+ 0x0000000030080000ULL,
+ 0x1c04000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x00000000511c0000ULL,
+ 0x2846000000000000ULL,
+ 0x00000000600c0000ULL,
+ 0x3406000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060080000ULL,
+ 0x3004000000000000ULL,
+ 0x0000000078040000ULL,
+ 0x3802000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051240000ULL,
+ 0x284a000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000600c0000ULL,
+ 0x3006000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x00000000512c0000ULL,
+ 0x284e000000000000ULL,
+ 0x0000000058080000ULL,
+ 0x3004000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060100000ULL,
+ 0x3008000000000000ULL,
+ 0x0000000078080000ULL,
+ 0x3804000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051340000ULL,
+ 0x2852000000000000ULL,
+ 0x00000000580c0000ULL,
+ 0x3006000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060140000ULL,
+ 0x300a000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3806000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051300000ULL,
+ 0x2850000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060180000ULL,
+ 0x300c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051380000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x2862000000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0xc200000004000000ULL
+ }
+#endif
+ },
+ { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x2854000000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0xc000000000000000ULL
+ }
+#endif
+ },
+ { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18c8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x2856000000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0xc000000004000000ULL
+ }
+#endif
+ },
+ { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18d0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0xc200000004000000ULL
+ },
+ {
+ -1ULL,
+ 0x2858000000000000ULL,
+ -1ULL,
+ -1ULL,
+ 0xc200000000000000ULL
+ }
+#endif
+ },
+ { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18d8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x1900000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x2860000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x285a000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18e0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x285c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18e8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x285e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18f0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x18f8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051440000ULL,
+ 0x2868000000000000ULL,
+ 0x00000000280c0000ULL,
+ 0x1806000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051400000ULL,
+ 0x2866000000000000ULL,
+ 0x0000000028080000ULL,
+ 0x1804000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000513c0000ULL,
+ 0x2864000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286b100000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286b180000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286b200000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286b280000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
+ { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051489000ULL,
+ -1ULL,
+ 0x00000000300c9000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
+ { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x000000005148a000ULL,
+ -1ULL,
+ 0x00000000300ca000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
+ { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x000000005148b000ULL,
+ -1ULL,
+ 0x00000000300cb000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
+ { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffff000ULL,
+ 0ULL,
+ 0x00000000780ff000ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x000000005148c000ULL,
+ -1ULL,
+ 0x00000000300cc000ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051500000ULL,
+ 0x286e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040800000ULL,
+ 0x1908000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000514c0000ULL,
+ 0x286c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051540000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051580000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000515c0000ULL,
+ 0x2870000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040900000ULL,
+ 0x1910000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051600000ULL,
+ 0x2872000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051640000ULL,
+ 0x2874000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051680000ULL,
+ 0x2876000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040a00000ULL,
+ 0x1918000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000516c0000ULL,
+ 0x2878000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040b00000ULL,
+ 0x1920000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051700000ULL,
+ 0x287a000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052880000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052840000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051780000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051740000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051880000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000517c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052900000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000528c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051840000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051800000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000518c0000ULL,
+ 0x287c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051900000ULL,
+ 0x287e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051940000ULL,
+ 0x2880000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040c00000ULL,
+ 0x1928000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051980000ULL,
+ 0x2882000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040d00000ULL,
+ 0x1930000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000519c0000ULL,
+ 0x2884000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051a00000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051a80000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051a40000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051ac0000ULL,
+ 0x2886000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051b00000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051b40000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051b80000ULL,
+ 0x2888000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000601c0000ULL,
+ 0x300e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051bc0000ULL,
+ 0x288a000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060200000ULL,
+ 0x3010000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051c00000ULL,
+ 0x288c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060240000ULL,
+ 0x3012000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051c80000ULL,
+ 0x2890000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051c40000ULL,
+ 0x288e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051d00000ULL,
+ 0x2894000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040e00000ULL,
+ 0x1938000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051cc0000ULL,
+ 0x2892000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051d40000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051d80000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051dc0000ULL,
+ 0x2896000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000040f00000ULL,
+ 0x1940000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051e00000ULL,
+ 0x2898000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051e40000ULL,
+ 0x289a000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051e80000ULL,
+ 0x289c000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000041000000ULL,
+ 0x1948000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051ec0000ULL,
+ 0x289e000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000041100000ULL,
+ 0x1950000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051f00000ULL,
+ 0x28a0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051f80000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051f40000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000051fc0000ULL,
+ 0x28a2000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052000000ULL,
+ 0x28a4000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052040000ULL,
+ 0x28a6000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000041200000ULL,
+ 0x1958000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052080000ULL,
+ 0x28a8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000041300000ULL,
+ 0x1960000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000520c0000ULL,
+ 0x28aa000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052100000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052140000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052180000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000521c0000ULL,
+ 0x28ac000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052200000ULL,
+ 0x28ae000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052240000ULL,
+ 0x28b0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052280000ULL,
+ 0x28b2000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000522c0000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1,
+ { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052300000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052340000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052380000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052400000ULL,
+ 0x28b6000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060280000ULL,
+ 0x3014000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000523c0000ULL,
+ 0x28b4000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052440000ULL,
+ 0x28b8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000602c0000ULL,
+ 0x3016000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052480000ULL,
+ 0x28ba000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000060300000ULL,
+ 0x3018000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052500000ULL,
+ 0x28be000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000524c0000ULL,
+ 0x28bc000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052580000ULL,
+ 0x28c2000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052540000ULL,
+ 0x28c0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000525c0000ULL,
+ 0x28c4000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052600000ULL,
+ 0x28c6000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052640000ULL,
+ 0x28c8000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000526c0000ULL,
+ 0x28cc000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052680000ULL,
+ 0x28ca000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052700000ULL,
+ 0x28ce000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052740000ULL,
+ 0x28d0000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x00000000527c0000ULL,
+ 0x28d4000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052780000ULL,
+ 0x28d2000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0ULL,
+ 0xfffff80000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ -1ULL,
+ 0x286b300000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
+ { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ffc0000ULL,
+ 0xfffe000000000000ULL,
+ 0x00000000780c0000ULL,
+ 0x3c06000000000000ULL,
+ 0ULL
+ },
+ {
+ 0x0000000052800000ULL,
+ 0x28d6000000000000ULL,
+ 0x00000000500c0000ULL,
+ 0x2c06000000000000ULL,
+ -1ULL
+ }
+#endif
+ },
+ { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
+ { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
+#ifndef DISASM_ONLY
+ {
+ 0xc00000007ff00000ULL,
+ 0xfff8000000000000ULL,
+ 0ULL,
+ 0ULL,
+ 0ULL
+ },
+ {
+ 0x0000000041400000ULL,
+ 0x1968000000000000ULL,
+ -1ULL,
+ -1ULL,
+ -1ULL
+ }
+#endif
+ },
+ { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
+#ifndef DISASM_ONLY
+ { 0, }, { 0, }
+#endif
+ }
+};
+
+#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
+#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index))
+
+static const unsigned short decode_X0_fsm[936] =
+{
+ BITFIELD(22, 9) /* index 0 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS,
+ TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU,
+ TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS,
+ TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM,
+ TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578),
+ CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671),
+ CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865),
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+ BITFIELD(6, 2) /* index 513 */,
+ TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
+ BITFIELD(8, 2) /* index 518 */,
+ TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
+ BITFIELD(10, 2) /* index 523 */,
+ TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
+ BITFIELD(20, 2) /* index 528 */,
+ TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
+ BITFIELD(6, 2) /* index 533 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
+ BITFIELD(8, 2) /* index 538 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
+ BITFIELD(10, 2) /* index 543 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+ BITFIELD(0, 2) /* index 548 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
+ BITFIELD(2, 2) /* index 553 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
+ BITFIELD(4, 2) /* index 558 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
+ BITFIELD(6, 2) /* index 563 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
+ BITFIELD(8, 2) /* index 568 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
+ BITFIELD(10, 2) /* index 573 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+ BITFIELD(20, 2) /* index 578 */,
+ TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI,
+ BITFIELD(20, 2) /* index 583 */,
+ TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI,
+ TILEGX_OPC_V1CMPLTUI,
+ BITFIELD(20, 2) /* index 588 */,
+ TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI,
+ TILEGX_OPC_V2CMPEQI,
+ BITFIELD(20, 2) /* index 593 */,
+ TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI,
+ TILEGX_OPC_V2MINSI,
+ BITFIELD(20, 2) /* index 598 */,
+ TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(18, 4) /* index 603 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
+ TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ,
+ TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+ TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR,
+ BITFIELD(18, 4) /* index 620 */,
+ TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL,
+ TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2,
+ TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN,
+ TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS,
+ TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1,
+ TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS,
+ BITFIELD(18, 4) /* index 637 */,
+ TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN,
+ TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2,
+ TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2,
+ TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX,
+ TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS,
+ TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS,
+ BITFIELD(18, 4) /* index 654 */,
+ TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU,
+ TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS,
+ TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU,
+ TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU,
+ TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU,
+ TILEGX_OPC_MZ,
+ BITFIELD(18, 4) /* index 671 */,
+ TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
+ TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
+ TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
+ TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES,
+ TILEGX_OPC_SUBXSC,
+ BITFIELD(12, 2) /* index 688 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693),
+ BITFIELD(14, 2) /* index 693 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698),
+ BITFIELD(16, 2) /* index 698 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+ BITFIELD(18, 4) /* index 703 */,
+ TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC,
+ TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU,
+ TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
+ TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
+ TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA,
+ BITFIELD(12, 4) /* index 720 */,
+ TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757),
+ CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787),
+ CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 737 */,
+ TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 742 */,
+ TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 747 */,
+ TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 752 */,
+ TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 757 */,
+ TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 762 */,
+ TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 767 */,
+ TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 772 */,
+ TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 777 */,
+ TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 782 */,
+ TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 787 */,
+ TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(16, 2) /* index 792 */,
+ TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(18, 4) /* index 797 */,
+ TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP,
+ TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU,
+ TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS,
+ TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU,
+ TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS,
+ BITFIELD(18, 4) /* index 814 */,
+ TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC,
+ TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS,
+ TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU,
+ TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE,
+ TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H,
+ BITFIELD(18, 4) /* index 831 */,
+ TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ,
+ TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ,
+ TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
+ TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS,
+ TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC,
+ BITFIELD(18, 4) /* index 848 */,
+ TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC,
+ TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
+ TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
+ TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
+ TILEGX_OPC_V4SUB,
+ BITFIELD(18, 3) /* index 865 */,
+ CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(21, 1) /* index 874 */,
+ TILEGX_OPC_XOR, TILEGX_OPC_NONE,
+ BITFIELD(21, 1) /* index 877 */,
+ TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE,
+ BITFIELD(21, 1) /* index 880 */,
+ TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE,
+ BITFIELD(21, 1) /* index 883 */,
+ TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE,
+ BITFIELD(21, 1) /* index 886 */,
+ TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE,
+ BITFIELD(18, 4) /* index 889 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
+ TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
+ TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
+ TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE,
+ BITFIELD(0, 2) /* index 906 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(911),
+ BITFIELD(2, 2) /* index 911 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(916),
+ BITFIELD(4, 2) /* index 916 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(921),
+ BITFIELD(6, 2) /* index 921 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(926),
+ BITFIELD(8, 2) /* index 926 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(931),
+ BITFIELD(10, 2) /* index 931 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ TILEGX_OPC_INFOL,
+};
+
+static const unsigned short decode_X1_fsm[1266] =
+{
+ BITFIELD(53, 9) /* index 0 */,
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+ CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+ TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT,
+ TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT,
+ TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT,
+ TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT,
+ TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST,
+ TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT,
+ TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT,
+ TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT,
+ TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578),
+ CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758),
+ CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+ TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J,
+ TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+ TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+ TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+ TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+ TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+ TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+ CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185),
+ CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
+ CHILD(1236),
+ BITFIELD(37, 2) /* index 513 */,
+ TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
+ BITFIELD(39, 2) /* index 518 */,
+ TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
+ BITFIELD(41, 2) /* index 523 */,
+ TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
+ BITFIELD(51, 2) /* index 528 */,
+ TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
+ BITFIELD(37, 2) /* index 533 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
+ BITFIELD(39, 2) /* index 538 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
+ BITFIELD(41, 2) /* index 543 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+ BITFIELD(31, 2) /* index 548 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
+ BITFIELD(33, 2) /* index 553 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
+ BITFIELD(35, 2) /* index 558 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
+ BITFIELD(37, 2) /* index 563 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
+ BITFIELD(39, 2) /* index 568 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
+ BITFIELD(41, 2) /* index 573 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+ BITFIELD(51, 2) /* index 578 */,
+ TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583),
+ BITFIELD(31, 2) /* index 583 */,
+ TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588),
+ BITFIELD(33, 2) /* index 588 */,
+ TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593),
+ BITFIELD(35, 2) /* index 593 */,
+ TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD,
+ TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
+ BITFIELD(51, 2) /* index 598 */,
+ CHILD(603), CHILD(618), CHILD(633), CHILD(648),
+ BITFIELD(31, 2) /* index 603 */,
+ TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608),
+ BITFIELD(33, 2) /* index 608 */,
+ TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613),
+ BITFIELD(35, 2) /* index 613 */,
+ TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD,
+ TILEGX_OPC_PREFETCH_ADD_L1,
+ BITFIELD(31, 2) /* index 618 */,
+ TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623),
+ BITFIELD(33, 2) /* index 623 */,
+ TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628),
+ BITFIELD(35, 2) /* index 628 */,
+ TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD,
+ TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
+ BITFIELD(31, 2) /* index 633 */,
+ TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638),
+ BITFIELD(33, 2) /* index 638 */,
+ TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643),
+ BITFIELD(35, 2) /* index 643 */,
+ TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD,
+ TILEGX_OPC_PREFETCH_ADD_L2,
+ BITFIELD(31, 2) /* index 648 */,
+ CHILD(653), CHILD(653), CHILD(653), CHILD(673),
+ BITFIELD(43, 2) /* index 653 */,
+ CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
+ BITFIELD(45, 2) /* index 658 */,
+ CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
+ BITFIELD(47, 2) /* index 663 */,
+ CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
+ BITFIELD(49, 2) /* index 668 */,
+ TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
+ TILEGX_OPC_LD4S_ADD,
+ BITFIELD(33, 2) /* index 673 */,
+ CHILD(653), CHILD(653), CHILD(653), CHILD(678),
+ BITFIELD(35, 2) /* index 678 */,
+ CHILD(653), CHILD(653), CHILD(653), CHILD(683),
+ BITFIELD(43, 2) /* index 683 */,
+ CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ BITFIELD(45, 2) /* index 688 */,
+ CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ BITFIELD(47, 2) /* index 693 */,
+ CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ BITFIELD(49, 2) /* index 698 */,
+ TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+ BITFIELD(51, 2) /* index 703 */,
+ CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD,
+ TILEGX_OPC_LDNT2S_ADD,
+ BITFIELD(31, 2) /* index 708 */,
+ TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713),
+ BITFIELD(33, 2) /* index 713 */,
+ TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718),
+ BITFIELD(35, 2) /* index 718 */,
+ TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD,
+ TILEGX_OPC_PREFETCH_ADD_L3,
+ BITFIELD(51, 2) /* index 723 */,
+ TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD,
+ TILEGX_OPC_LDNT_ADD,
+ BITFIELD(51, 2) /* index 728 */,
+ CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR,
+ BITFIELD(43, 2) /* index 733 */,
+ CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
+ BITFIELD(45, 2) /* index 738 */,
+ CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
+ BITFIELD(47, 2) /* index 743 */,
+ CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
+ BITFIELD(49, 2) /* index 748 */,
+ TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
+ BITFIELD(51, 2) /* index 753 */,
+ TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD,
+ BITFIELD(51, 2) /* index 758 */,
+ TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD,
+ TILEGX_OPC_STNT_ADD,
+ BITFIELD(51, 2) /* index 763 */,
+ TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI,
+ TILEGX_OPC_V1CMPLTSI,
+ BITFIELD(51, 2) /* index 768 */,
+ TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI,
+ TILEGX_OPC_V2ADDI,
+ BITFIELD(51, 2) /* index 773 */,
+ TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI,
+ TILEGX_OPC_V2MAXSI,
+ BITFIELD(51, 2) /* index 778 */,
+ TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(49, 4) /* index 783 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
+ TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH,
+ TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+ TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4,
+ TILEGX_OPC_DBLALIGN6,
+ BITFIELD(49, 4) /* index 800 */,
+ TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4,
+ TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD,
+ TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4,
+ TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR,
+ CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
+ BITFIELD(43, 2) /* index 817 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822),
+ BITFIELD(45, 2) /* index 822 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827),
+ BITFIELD(47, 2) /* index 827 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+ BITFIELD(49, 4) /* index 832 */,
+ TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
+ TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
+ TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1,
+ TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2,
+ TILEGX_OPC_STNT4,
+ BITFIELD(46, 7) /* index 849 */,
+ TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
+ TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
+ TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST,
+ TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC,
+ TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC,
+ TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX,
+ TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX,
+ TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
+ TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB,
+ TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987),
+ CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
+ TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
+ TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
+ TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
+ TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
+ TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
+ TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
+ TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
+ TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
+ TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
+ TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
+ TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
+ TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
+ TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
+ TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
+ TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
+ TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
+ TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
+ TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
+ TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
+ TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
+ TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
+ TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
+ TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
+ TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
+ TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
+ BITFIELD(43, 3) /* index 978 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV,
+ TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH,
+ BITFIELD(43, 3) /* index 987 */,
+ CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP,
+ TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051),
+ BITFIELD(31, 2) /* index 996 */,
+ CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+ BITFIELD(33, 2) /* index 1001 */,
+ TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006),
+ BITFIELD(35, 2) /* index 1006 */,
+ TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+ BITFIELD(37, 2) /* index 1011 */,
+ TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+ BITFIELD(39, 2) /* index 1016 */,
+ TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+ BITFIELD(41, 2) /* index 1021 */,
+ TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL,
+ BITFIELD(33, 2) /* index 1026 */,
+ TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031),
+ BITFIELD(35, 2) /* index 1031 */,
+ TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+ BITFIELD(37, 2) /* index 1036 */,
+ TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+ BITFIELD(39, 2) /* index 1041 */,
+ TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+ BITFIELD(41, 2) /* index 1046 */,
+ TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL,
+ BITFIELD(31, 2) /* index 1051 */,
+ TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056),
+ BITFIELD(33, 2) /* index 1056 */,
+ TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061),
+ BITFIELD(35, 2) /* index 1061 */,
+ TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
+ TILEGX_OPC_PREFETCH_L1_FAULT,
+ BITFIELD(43, 3) /* index 1066 */,
+ CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135),
+ TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U,
+ BITFIELD(31, 2) /* index 1075 */,
+ TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080),
+ BITFIELD(33, 2) /* index 1080 */,
+ TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085),
+ BITFIELD(35, 2) /* index 1085 */,
+ TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
+ BITFIELD(31, 2) /* index 1090 */,
+ TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095),
+ BITFIELD(33, 2) /* index 1095 */,
+ TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100),
+ BITFIELD(35, 2) /* index 1100 */,
+ TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
+ TILEGX_OPC_PREFETCH_L2_FAULT,
+ BITFIELD(31, 2) /* index 1105 */,
+ TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110),
+ BITFIELD(33, 2) /* index 1110 */,
+ TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115),
+ BITFIELD(35, 2) /* index 1115 */,
+ TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
+ BITFIELD(31, 2) /* index 1120 */,
+ TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125),
+ BITFIELD(33, 2) /* index 1125 */,
+ TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130),
+ BITFIELD(35, 2) /* index 1130 */,
+ TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S,
+ TILEGX_OPC_PREFETCH_L3_FAULT,
+ BITFIELD(31, 2) /* index 1135 */,
+ TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140),
+ BITFIELD(33, 2) /* index 1140 */,
+ TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145),
+ BITFIELD(35, 2) /* index 1145 */,
+ TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
+ BITFIELD(43, 3) /* index 1150 */,
+ TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U,
+ TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF,
+ BITFIELD(43, 3) /* index 1159 */,
+ TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1,
+ TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE,
+ BITFIELD(49, 4) /* index 1168 */,
+ TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ,
+ TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC,
+ TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ,
+ TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS,
+ TILEGX_OPC_V2CMPLTU,
+ BITFIELD(49, 4) /* index 1185 */,
+ TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L,
+ TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ,
+ TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
+ TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU,
+ TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB,
+ BITFIELD(49, 4) /* index 1202 */,
+ TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
+ TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
+ TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
+ TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(49, 4) /* index 1219 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
+ TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
+ TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
+ TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE,
+ BITFIELD(31, 2) /* index 1236 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(1241),
+ BITFIELD(33, 2) /* index 1241 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(1246),
+ BITFIELD(35, 2) /* index 1246 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(1251),
+ BITFIELD(37, 2) /* index 1251 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(1256),
+ BITFIELD(39, 2) /* index 1256 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ CHILD(1261),
+ BITFIELD(41, 2) /* index 1261 */,
+ TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+ TILEGX_OPC_INFOL,
+};
+
+static const unsigned short decode_Y0_fsm[178] =
+{
+ BITFIELD(27, 4) /* index 0 */,
+ CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
+ TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123),
+ CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168),
+ CHILD(173),
+ BITFIELD(6, 2) /* index 17 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
+ BITFIELD(8, 2) /* index 22 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
+ BITFIELD(10, 2) /* index 27 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+ BITFIELD(0, 2) /* index 32 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
+ BITFIELD(2, 2) /* index 37 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
+ BITFIELD(4, 2) /* index 42 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
+ BITFIELD(6, 2) /* index 47 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
+ BITFIELD(8, 2) /* index 52 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
+ BITFIELD(10, 2) /* index 57 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+ BITFIELD(18, 2) /* index 62 */,
+ TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
+ BITFIELD(15, 5) /* index 67 */,
+ TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
+ TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
+ TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD,
+ TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
+ TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
+ TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
+ TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
+ TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100),
+ CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(12, 3) /* index 100 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP,
+ TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT,
+ TILEGX_OPC_REVBITS,
+ BITFIELD(12, 3) /* index 109 */,
+ TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1,
+ TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ TILEGX_OPC_NONE,
+ BITFIELD(18, 2) /* index 118 */,
+ TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+ BITFIELD(18, 2) /* index 123 */,
+ TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX,
+ BITFIELD(18, 2) /* index 128 */,
+ TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
+ BITFIELD(18, 2) /* index 133 */,
+ TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR,
+ BITFIELD(12, 2) /* index 138 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143),
+ BITFIELD(14, 2) /* index 143 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148),
+ BITFIELD(16, 2) /* index 148 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+ BITFIELD(18, 2) /* index 153 */,
+ TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
+ BITFIELD(18, 2) /* index 158 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
+ TILEGX_OPC_SHL3ADDX,
+ BITFIELD(18, 2) /* index 163 */,
+ TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS,
+ TILEGX_OPC_MUL_LU_LU,
+ BITFIELD(18, 2) /* index 168 */,
+ TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS,
+ TILEGX_OPC_MULA_LU_LU,
+ BITFIELD(18, 2) /* index 173 */,
+ TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
+};
+
+static const unsigned short decode_Y1_fsm[167] =
+{
+ BITFIELD(58, 4) /* index 0 */,
+ TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
+ TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122),
+ CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE,
+ BITFIELD(37, 2) /* index 17 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
+ BITFIELD(39, 2) /* index 22 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
+ BITFIELD(41, 2) /* index 27 */,
+ TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+ BITFIELD(31, 2) /* index 32 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
+ BITFIELD(33, 2) /* index 37 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
+ BITFIELD(35, 2) /* index 42 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
+ BITFIELD(37, 2) /* index 47 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
+ BITFIELD(39, 2) /* index 52 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
+ BITFIELD(41, 2) /* index 57 */,
+ TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+ BITFIELD(49, 2) /* index 62 */,
+ TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
+ BITFIELD(47, 4) /* index 67 */,
+ TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
+ TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
+ TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD,
+ TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84),
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+ BITFIELD(43, 3) /* index 84 */,
+ CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108),
+ CHILD(111), CHILD(114),
+ BITFIELD(46, 1) /* index 93 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_FNOP,
+ BITFIELD(46, 1) /* index 96 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_ILL,
+ BITFIELD(46, 1) /* index 99 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_JALRP,
+ BITFIELD(46, 1) /* index 102 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_JALR,
+ BITFIELD(46, 1) /* index 105 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_JRP,
+ BITFIELD(46, 1) /* index 108 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_JR,
+ BITFIELD(46, 1) /* index 111 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_LNK,
+ BITFIELD(46, 1) /* index 114 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_NOP,
+ BITFIELD(49, 2) /* index 117 */,
+ TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+ BITFIELD(49, 2) /* index 122 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE,
+ BITFIELD(49, 2) /* index 127 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
+ BITFIELD(49, 2) /* index 132 */,
+ TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR,
+ BITFIELD(43, 2) /* index 137 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142),
+ BITFIELD(45, 2) /* index 142 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147),
+ BITFIELD(47, 2) /* index 147 */,
+ TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+ BITFIELD(49, 2) /* index 152 */,
+ TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
+ BITFIELD(49, 2) /* index 157 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
+ TILEGX_OPC_SHL3ADDX,
+ BITFIELD(49, 2) /* index 162 */,
+ TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
+};
+
+static const unsigned short decode_Y2_fsm[118] =
+{
+ BITFIELD(62, 2) /* index 0 */,
+ TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109),
+ BITFIELD(55, 3) /* index 5 */,
+ CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40),
+ CHILD(43),
+ BITFIELD(26, 1) /* index 14 */,
+ TILEGX_OPC_LD1S, TILEGX_OPC_LD1U,
+ BITFIELD(26, 1) /* index 17 */,
+ CHILD(20), CHILD(30),
+ BITFIELD(51, 2) /* index 20 */,
+ TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25),
+ BITFIELD(53, 2) /* index 25 */,
+ TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
+ TILEGX_OPC_PREFETCH_L1_FAULT,
+ BITFIELD(51, 2) /* index 30 */,
+ TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35),
+ BITFIELD(53, 2) /* index 35 */,
+ TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
+ BITFIELD(26, 1) /* index 40 */,
+ TILEGX_OPC_LD2S, TILEGX_OPC_LD2U,
+ BITFIELD(26, 1) /* index 43 */,
+ CHILD(46), CHILD(56),
+ BITFIELD(51, 2) /* index 46 */,
+ TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51),
+ BITFIELD(53, 2) /* index 51 */,
+ TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
+ TILEGX_OPC_PREFETCH_L2_FAULT,
+ BITFIELD(51, 2) /* index 56 */,
+ TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61),
+ BITFIELD(53, 2) /* index 61 */,
+ TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
+ BITFIELD(56, 2) /* index 66 */,
+ CHILD(71), CHILD(74), CHILD(90), CHILD(93),
+ BITFIELD(26, 1) /* index 71 */,
+ TILEGX_OPC_NONE, TILEGX_OPC_LD4S,
+ BITFIELD(26, 1) /* index 74 */,
+ TILEGX_OPC_NONE, CHILD(77),
+ BITFIELD(51, 2) /* index 77 */,
+ TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82),
+ BITFIELD(53, 2) /* index 82 */,
+ TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87),
+ BITFIELD(55, 1) /* index 87 */,
+ TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT,
+ BITFIELD(26, 1) /* index 90 */,
+ TILEGX_OPC_LD4U, TILEGX_OPC_LD,
+ BITFIELD(26, 1) /* index 93 */,
+ CHILD(96), TILEGX_OPC_LD,
+ BITFIELD(51, 2) /* index 96 */,
+ TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101),
+ BITFIELD(53, 2) /* index 101 */,
+ TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106),
+ BITFIELD(55, 1) /* index 106 */,
+ TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
+ BITFIELD(26, 1) /* index 109 */,
+ CHILD(112), CHILD(115),
+ BITFIELD(57, 1) /* index 112 */,
+ TILEGX_OPC_ST1, TILEGX_OPC_ST4,
+ BITFIELD(57, 1) /* index 115 */,
+ TILEGX_OPC_ST2, TILEGX_OPC_ST,
+};
+
+#undef BITFIELD
+#undef CHILD
+
+const unsigned short * const
+tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] =
+{
+ decode_X0_fsm,
+ decode_X1_fsm,
+ decode_Y0_fsm,
+ decode_Y1_fsm,
+ decode_Y2_fsm
+};
+
+const struct tilegx_operand tilegx_operands[35] =
+{
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_X0, get_Imm8_X0
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_X1, get_Imm8_X1
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_Y0, get_Imm8_Y0
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_Y1, get_Imm8_Y1
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST),
+ 16, 1, 0, 0, 0, 0,
+ create_Imm16_X0, get_Imm16_X0
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST),
+ 16, 1, 0, 0, 0, 0,
+ create_Imm16_X1, get_Imm16_X1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_X1, get_Dest_X1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_X1, get_SrcA_X1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_X0, get_Dest_X0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_X0, get_SrcA_X0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_Y0, get_Dest_Y0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_Y0, get_SrcA_Y0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_Y1, get_Dest_Y1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_Y1, get_SrcA_Y1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_Y2, get_SrcA_Y2
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 1, 0, 0,
+ create_SrcA_X1, get_SrcA_X1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_X0, get_SrcB_X0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_X1, get_SrcB_X1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_Y0, get_SrcB_Y0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_Y1, get_SrcB_Y1
+ },
+ {
+ TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1),
+ 17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+ create_BrOff_X1, get_BrOff_X1
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0),
+ 6, 0, 0, 0, 0, 0,
+ create_BFStart_X0, get_BFStart_X0
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0),
+ 6, 0, 0, 0, 0, 0,
+ create_BFEnd_X0, get_BFEnd_X0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 1, 0, 0,
+ create_Dest_X0, get_Dest_X0
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 1, 0, 0,
+ create_Dest_Y0, get_Dest_Y0
+ },
+ {
+ TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1),
+ 27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+ create_JumpOff_X1, get_JumpOff_X1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_SrcBDest_Y2, get_SrcBDest_Y2
+ },
+ {
+ TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1),
+ 14, 0, 0, 0, 0, 0,
+ create_MF_Imm14_X1, get_MF_Imm14_X1
+ },
+ {
+ TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1),
+ 14, 0, 0, 0, 0, 0,
+ create_MT_Imm14_X1, get_MT_Imm14_X1
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0),
+ 6, 0, 0, 0, 0, 0,
+ create_ShAmt_X0, get_ShAmt_X0
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1),
+ 6, 0, 0, 0, 0, 0,
+ create_ShAmt_X1, get_ShAmt_X1
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0),
+ 6, 0, 0, 0, 0, 0,
+ create_ShAmt_Y0, get_ShAmt_Y0
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1),
+ 6, 0, 0, 0, 0, 0,
+ create_ShAmt_Y1, get_ShAmt_Y1
+ },
+ {
+ TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcBDest_Y2, get_SrcBDest_Y2
+ },
+ {
+ TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1),
+ 8, 1, 0, 0, 0, 0,
+ create_Dest_Imm8_X1, get_Dest_Imm8_X1
+ }
+};
+
+/* Given a set of bundle bits and a specific pipe, returns which
+ * instruction the bundle contains in that pipe.
+ */
+const struct tilegx_opcode *
+find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe)
+{
+ const unsigned short *table = tilegx_bundle_decoder_fsms[pipe];
+ int index = 0;
+
+ while (1)
+ {
+ unsigned short bitspec = table[index];
+ unsigned int bitfield =
+ ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
+
+ unsigned short next = table[index + 1 + bitfield];
+ if (next <= TILEGX_OPC_NONE)
+ return &tilegx_opcodes[next];
+
+ index = next - TILEGX_OPC_NONE;
+ }
+}
+
+int
+parse_insn_tilegx(tilegx_bundle_bits bits,
+ unsigned long long pc,
+ struct tilegx_decoded_instruction
+ decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE])
+{
+ int num_instructions = 0;
+ int pipe;
+
+ int min_pipe, max_pipe;
+ if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0)
+ {
+ min_pipe = TILEGX_PIPELINE_X0;
+ max_pipe = TILEGX_PIPELINE_X1;
+ }
+ else
+ {
+ min_pipe = TILEGX_PIPELINE_Y0;
+ max_pipe = TILEGX_PIPELINE_Y2;
+ }
+
+ /* For each pipe, find an instruction that fits. */
+ for (pipe = min_pipe; pipe <= max_pipe; pipe++)
+ {
+ const struct tilegx_opcode *opc;
+ struct tilegx_decoded_instruction *d;
+ int i;
+
+ d = &decoded[num_instructions++];
+ opc = find_opcode (bits, (tilegx_pipeline)pipe);
+ d->opcode = opc;
+
+ /* Decode each operand, sign extending, etc. as appropriate. */
+ for (i = 0; i < opc->num_operands; i++)
+ {
+ const struct tilegx_operand *op =
+ &tilegx_operands[opc->operands[pipe][i]];
+ int raw_opval = op->extract (bits);
+ long long opval;
+
+ if (op->is_signed)
+ {
+ /* Sign-extend the operand. */
+ int shift = (int)((sizeof(int) * 8) - op->num_bits);
+ raw_opval = (raw_opval << shift) >> shift;
+ }
+
+ /* Adjust PC-relative scaled branch offsets. */
+ if (op->type == TILEGX_OP_TYPE_ADDRESS)
+ opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc;
+ else
+ opval = raw_opval;
+
+ /* Record the final value. */
+ d->operands[i] = op;
+ d->operand_values[i] = opval;
+ }
+ }
+
+ return num_instructions;
+}
+
+struct tilegx_spr
+{
+ /* The number */
+ int number;
+
+ /* The name */
+ const char *name;
+};
+
+static int
+tilegx_spr_compare (const void *a_ptr, const void *b_ptr)
+{
+ const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr;
+ const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr;
+ return (a->number - b->number);
+}
+
+const struct tilegx_spr tilegx_sprs[] = {
+ { 0, "MPL_MEM_ERROR_SET_0" },
+ { 1, "MPL_MEM_ERROR_SET_1" },
+ { 2, "MPL_MEM_ERROR_SET_2" },
+ { 3, "MPL_MEM_ERROR_SET_3" },
+ { 4, "MPL_MEM_ERROR" },
+ { 5, "MEM_ERROR_CBOX_ADDR" },
+ { 6, "MEM_ERROR_CBOX_STATUS" },
+ { 7, "MEM_ERROR_ENABLE" },
+ { 8, "MEM_ERROR_MBOX_ADDR" },
+ { 9, "MEM_ERROR_MBOX_STATUS" },
+ { 10, "SBOX_ERROR" },
+ { 11, "XDN_DEMUX_ERROR" },
+ { 256, "MPL_SINGLE_STEP_3_SET_0" },
+ { 257, "MPL_SINGLE_STEP_3_SET_1" },
+ { 258, "MPL_SINGLE_STEP_3_SET_2" },
+ { 259, "MPL_SINGLE_STEP_3_SET_3" },
+ { 260, "MPL_SINGLE_STEP_3" },
+ { 261, "SINGLE_STEP_CONTROL_3" },
+ { 512, "MPL_SINGLE_STEP_2_SET_0" },
+ { 513, "MPL_SINGLE_STEP_2_SET_1" },
+ { 514, "MPL_SINGLE_STEP_2_SET_2" },
+ { 515, "MPL_SINGLE_STEP_2_SET_3" },
+ { 516, "MPL_SINGLE_STEP_2" },
+ { 517, "SINGLE_STEP_CONTROL_2" },
+ { 768, "MPL_SINGLE_STEP_1_SET_0" },
+ { 769, "MPL_SINGLE_STEP_1_SET_1" },
+ { 770, "MPL_SINGLE_STEP_1_SET_2" },
+ { 771, "MPL_SINGLE_STEP_1_SET_3" },
+ { 772, "MPL_SINGLE_STEP_1" },
+ { 773, "SINGLE_STEP_CONTROL_1" },
+ { 1024, "MPL_SINGLE_STEP_0_SET_0" },
+ { 1025, "MPL_SINGLE_STEP_0_SET_1" },
+ { 1026, "MPL_SINGLE_STEP_0_SET_2" },
+ { 1027, "MPL_SINGLE_STEP_0_SET_3" },
+ { 1028, "MPL_SINGLE_STEP_0" },
+ { 1029, "SINGLE_STEP_CONTROL_0" },
+ { 1280, "MPL_IDN_COMPLETE_SET_0" },
+ { 1281, "MPL_IDN_COMPLETE_SET_1" },
+ { 1282, "MPL_IDN_COMPLETE_SET_2" },
+ { 1283, "MPL_IDN_COMPLETE_SET_3" },
+ { 1284, "MPL_IDN_COMPLETE" },
+ { 1285, "IDN_COMPLETE_PENDING" },
+ { 1536, "MPL_UDN_COMPLETE_SET_0" },
+ { 1537, "MPL_UDN_COMPLETE_SET_1" },
+ { 1538, "MPL_UDN_COMPLETE_SET_2" },
+ { 1539, "MPL_UDN_COMPLETE_SET_3" },
+ { 1540, "MPL_UDN_COMPLETE" },
+ { 1541, "UDN_COMPLETE_PENDING" },
+ { 1792, "MPL_ITLB_MISS_SET_0" },
+ { 1793, "MPL_ITLB_MISS_SET_1" },
+ { 1794, "MPL_ITLB_MISS_SET_2" },
+ { 1795, "MPL_ITLB_MISS_SET_3" },
+ { 1796, "MPL_ITLB_MISS" },
+ { 1797, "ITLB_TSB_BASE_ADDR_0" },
+ { 1798, "ITLB_TSB_BASE_ADDR_1" },
+ { 1920, "ITLB_CURRENT_ATTR" },
+ { 1921, "ITLB_CURRENT_PA" },
+ { 1922, "ITLB_CURRENT_VA" },
+ { 1923, "ITLB_INDEX" },
+ { 1924, "ITLB_MATCH_0" },
+ { 1925, "ITLB_PERF" },
+ { 1926, "ITLB_PR" },
+ { 1927, "ITLB_TSB_ADDR_0" },
+ { 1928, "ITLB_TSB_ADDR_1" },
+ { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" },
+ { 1930, "ITLB_TSB_FILL_MATCH" },
+ { 1931, "NUMBER_ITLB" },
+ { 1932, "REPLACEMENT_ITLB" },
+ { 1933, "WIRED_ITLB" },
+ { 2048, "MPL_ILL_SET_0" },
+ { 2049, "MPL_ILL_SET_1" },
+ { 2050, "MPL_ILL_SET_2" },
+ { 2051, "MPL_ILL_SET_3" },
+ { 2052, "MPL_ILL" },
+ { 2304, "MPL_GPV_SET_0" },
+ { 2305, "MPL_GPV_SET_1" },
+ { 2306, "MPL_GPV_SET_2" },
+ { 2307, "MPL_GPV_SET_3" },
+ { 2308, "MPL_GPV" },
+ { 2309, "GPV_REASON" },
+ { 2560, "MPL_IDN_ACCESS_SET_0" },
+ { 2561, "MPL_IDN_ACCESS_SET_1" },
+ { 2562, "MPL_IDN_ACCESS_SET_2" },
+ { 2563, "MPL_IDN_ACCESS_SET_3" },
+ { 2564, "MPL_IDN_ACCESS" },
+ { 2565, "IDN_DEMUX_COUNT_0" },
+ { 2566, "IDN_DEMUX_COUNT_1" },
+ { 2567, "IDN_FLUSH_EGRESS" },
+ { 2568, "IDN_PENDING" },
+ { 2569, "IDN_ROUTE_ORDER" },
+ { 2570, "IDN_SP_FIFO_CNT" },
+ { 2688, "IDN_DATA_AVAIL" },
+ { 2816, "MPL_UDN_ACCESS_SET_0" },
+ { 2817, "MPL_UDN_ACCESS_SET_1" },
+ { 2818, "MPL_UDN_ACCESS_SET_2" },
+ { 2819, "MPL_UDN_ACCESS_SET_3" },
+ { 2820, "MPL_UDN_ACCESS" },
+ { 2821, "UDN_DEMUX_COUNT_0" },
+ { 2822, "UDN_DEMUX_COUNT_1" },
+ { 2823, "UDN_DEMUX_COUNT_2" },
+ { 2824, "UDN_DEMUX_COUNT_3" },
+ { 2825, "UDN_FLUSH_EGRESS" },
+ { 2826, "UDN_PENDING" },
+ { 2827, "UDN_ROUTE_ORDER" },
+ { 2828, "UDN_SP_FIFO_CNT" },
+ { 2944, "UDN_DATA_AVAIL" },
+ { 3072, "MPL_SWINT_3_SET_0" },
+ { 3073, "MPL_SWINT_3_SET_1" },
+ { 3074, "MPL_SWINT_3_SET_2" },
+ { 3075, "MPL_SWINT_3_SET_3" },
+ { 3076, "MPL_SWINT_3" },
+ { 3328, "MPL_SWINT_2_SET_0" },
+ { 3329, "MPL_SWINT_2_SET_1" },
+ { 3330, "MPL_SWINT_2_SET_2" },
+ { 3331, "MPL_SWINT_2_SET_3" },
+ { 3332, "MPL_SWINT_2" },
+ { 3584, "MPL_SWINT_1_SET_0" },
+ { 3585, "MPL_SWINT_1_SET_1" },
+ { 3586, "MPL_SWINT_1_SET_2" },
+ { 3587, "MPL_SWINT_1_SET_3" },
+ { 3588, "MPL_SWINT_1" },
+ { 3840, "MPL_SWINT_0_SET_0" },
+ { 3841, "MPL_SWINT_0_SET_1" },
+ { 3842, "MPL_SWINT_0_SET_2" },
+ { 3843, "MPL_SWINT_0_SET_3" },
+ { 3844, "MPL_SWINT_0" },
+ { 4096, "MPL_ILL_TRANS_SET_0" },
+ { 4097, "MPL_ILL_TRANS_SET_1" },
+ { 4098, "MPL_ILL_TRANS_SET_2" },
+ { 4099, "MPL_ILL_TRANS_SET_3" },
+ { 4100, "MPL_ILL_TRANS" },
+ { 4101, "ILL_TRANS_REASON" },
+ { 4102, "ILL_VA_PC" },
+ { 4352, "MPL_UNALIGN_DATA_SET_0" },
+ { 4353, "MPL_UNALIGN_DATA_SET_1" },
+ { 4354, "MPL_UNALIGN_DATA_SET_2" },
+ { 4355, "MPL_UNALIGN_DATA_SET_3" },
+ { 4356, "MPL_UNALIGN_DATA" },
+ { 4608, "MPL_DTLB_MISS_SET_0" },
+ { 4609, "MPL_DTLB_MISS_SET_1" },
+ { 4610, "MPL_DTLB_MISS_SET_2" },
+ { 4611, "MPL_DTLB_MISS_SET_3" },
+ { 4612, "MPL_DTLB_MISS" },
+ { 4613, "DTLB_TSB_BASE_ADDR_0" },
+ { 4614, "DTLB_TSB_BASE_ADDR_1" },
+ { 4736, "AAR" },
+ { 4737, "CACHE_PINNED_WAYS" },
+ { 4738, "DTLB_BAD_ADDR" },
+ { 4739, "DTLB_BAD_ADDR_REASON" },
+ { 4740, "DTLB_CURRENT_ATTR" },
+ { 4741, "DTLB_CURRENT_PA" },
+ { 4742, "DTLB_CURRENT_VA" },
+ { 4743, "DTLB_INDEX" },
+ { 4744, "DTLB_MATCH_0" },
+ { 4745, "DTLB_PERF" },
+ { 4746, "DTLB_TSB_ADDR_0" },
+ { 4747, "DTLB_TSB_ADDR_1" },
+ { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" },
+ { 4749, "DTLB_TSB_FILL_MATCH" },
+ { 4750, "NUMBER_DTLB" },
+ { 4751, "REPLACEMENT_DTLB" },
+ { 4752, "WIRED_DTLB" },
+ { 4864, "MPL_DTLB_ACCESS_SET_0" },
+ { 4865, "MPL_DTLB_ACCESS_SET_1" },
+ { 4866, "MPL_DTLB_ACCESS_SET_2" },
+ { 4867, "MPL_DTLB_ACCESS_SET_3" },
+ { 4868, "MPL_DTLB_ACCESS" },
+ { 5120, "MPL_IDN_FIREWALL_SET_0" },
+ { 5121, "MPL_IDN_FIREWALL_SET_1" },
+ { 5122, "MPL_IDN_FIREWALL_SET_2" },
+ { 5123, "MPL_IDN_FIREWALL_SET_3" },
+ { 5124, "MPL_IDN_FIREWALL" },
+ { 5125, "IDN_DIRECTION_PROTECT" },
+ { 5376, "MPL_UDN_FIREWALL_SET_0" },
+ { 5377, "MPL_UDN_FIREWALL_SET_1" },
+ { 5378, "MPL_UDN_FIREWALL_SET_2" },
+ { 5379, "MPL_UDN_FIREWALL_SET_3" },
+ { 5380, "MPL_UDN_FIREWALL" },
+ { 5381, "UDN_DIRECTION_PROTECT" },
+ { 5632, "MPL_TILE_TIMER_SET_0" },
+ { 5633, "MPL_TILE_TIMER_SET_1" },
+ { 5634, "MPL_TILE_TIMER_SET_2" },
+ { 5635, "MPL_TILE_TIMER_SET_3" },
+ { 5636, "MPL_TILE_TIMER" },
+ { 5637, "TILE_TIMER_CONTROL" },
+ { 5888, "MPL_AUX_TILE_TIMER_SET_0" },
+ { 5889, "MPL_AUX_TILE_TIMER_SET_1" },
+ { 5890, "MPL_AUX_TILE_TIMER_SET_2" },
+ { 5891, "MPL_AUX_TILE_TIMER_SET_3" },
+ { 5892, "MPL_AUX_TILE_TIMER" },
+ { 5893, "AUX_TILE_TIMER_CONTROL" },
+ { 6144, "MPL_IDN_TIMER_SET_0" },
+ { 6145, "MPL_IDN_TIMER_SET_1" },
+ { 6146, "MPL_IDN_TIMER_SET_2" },
+ { 6147, "MPL_IDN_TIMER_SET_3" },
+ { 6148, "MPL_IDN_TIMER" },
+ { 6149, "IDN_DEADLOCK_COUNT" },
+ { 6150, "IDN_DEADLOCK_TIMEOUT" },
+ { 6400, "MPL_UDN_TIMER_SET_0" },
+ { 6401, "MPL_UDN_TIMER_SET_1" },
+ { 6402, "MPL_UDN_TIMER_SET_2" },
+ { 6403, "MPL_UDN_TIMER_SET_3" },
+ { 6404, "MPL_UDN_TIMER" },
+ { 6405, "UDN_DEADLOCK_COUNT" },
+ { 6406, "UDN_DEADLOCK_TIMEOUT" },
+ { 6656, "MPL_IDN_AVAIL_SET_0" },
+ { 6657, "MPL_IDN_AVAIL_SET_1" },
+ { 6658, "MPL_IDN_AVAIL_SET_2" },
+ { 6659, "MPL_IDN_AVAIL_SET_3" },
+ { 6660, "MPL_IDN_AVAIL" },
+ { 6661, "IDN_AVAIL_EN" },
+ { 6912, "MPL_UDN_AVAIL_SET_0" },
+ { 6913, "MPL_UDN_AVAIL_SET_1" },
+ { 6914, "MPL_UDN_AVAIL_SET_2" },
+ { 6915, "MPL_UDN_AVAIL_SET_3" },
+ { 6916, "MPL_UDN_AVAIL" },
+ { 6917, "UDN_AVAIL_EN" },
+ { 7168, "MPL_IPI_3_SET_0" },
+ { 7169, "MPL_IPI_3_SET_1" },
+ { 7170, "MPL_IPI_3_SET_2" },
+ { 7171, "MPL_IPI_3_SET_3" },
+ { 7172, "MPL_IPI_3" },
+ { 7173, "IPI_EVENT_3" },
+ { 7174, "IPI_EVENT_RESET_3" },
+ { 7175, "IPI_EVENT_SET_3" },
+ { 7176, "IPI_MASK_3" },
+ { 7177, "IPI_MASK_RESET_3" },
+ { 7178, "IPI_MASK_SET_3" },
+ { 7424, "MPL_IPI_2_SET_0" },
+ { 7425, "MPL_IPI_2_SET_1" },
+ { 7426, "MPL_IPI_2_SET_2" },
+ { 7427, "MPL_IPI_2_SET_3" },
+ { 7428, "MPL_IPI_2" },
+ { 7429, "IPI_EVENT_2" },
+ { 7430, "IPI_EVENT_RESET_2" },
+ { 7431, "IPI_EVENT_SET_2" },
+ { 7432, "IPI_MASK_2" },
+ { 7433, "IPI_MASK_RESET_2" },
+ { 7434, "IPI_MASK_SET_2" },
+ { 7680, "MPL_IPI_1_SET_0" },
+ { 7681, "MPL_IPI_1_SET_1" },
+ { 7682, "MPL_IPI_1_SET_2" },
+ { 7683, "MPL_IPI_1_SET_3" },
+ { 7684, "MPL_IPI_1" },
+ { 7685, "IPI_EVENT_1" },
+ { 7686, "IPI_EVENT_RESET_1" },
+ { 7687, "IPI_EVENT_SET_1" },
+ { 7688, "IPI_MASK_1" },
+ { 7689, "IPI_MASK_RESET_1" },
+ { 7690, "IPI_MASK_SET_1" },
+ { 7936, "MPL_IPI_0_SET_0" },
+ { 7937, "MPL_IPI_0_SET_1" },
+ { 7938, "MPL_IPI_0_SET_2" },
+ { 7939, "MPL_IPI_0_SET_3" },
+ { 7940, "MPL_IPI_0" },
+ { 7941, "IPI_EVENT_0" },
+ { 7942, "IPI_EVENT_RESET_0" },
+ { 7943, "IPI_EVENT_SET_0" },
+ { 7944, "IPI_MASK_0" },
+ { 7945, "IPI_MASK_RESET_0" },
+ { 7946, "IPI_MASK_SET_0" },
+ { 8192, "MPL_PERF_COUNT_SET_0" },
+ { 8193, "MPL_PERF_COUNT_SET_1" },
+ { 8194, "MPL_PERF_COUNT_SET_2" },
+ { 8195, "MPL_PERF_COUNT_SET_3" },
+ { 8196, "MPL_PERF_COUNT" },
+ { 8197, "PERF_COUNT_0" },
+ { 8198, "PERF_COUNT_1" },
+ { 8199, "PERF_COUNT_CTL" },
+ { 8200, "PERF_COUNT_DN_CTL" },
+ { 8201, "PERF_COUNT_STS" },
+ { 8202, "WATCH_MASK" },
+ { 8203, "WATCH_VAL" },
+ { 8448, "MPL_AUX_PERF_COUNT_SET_0" },
+ { 8449, "MPL_AUX_PERF_COUNT_SET_1" },
+ { 8450, "MPL_AUX_PERF_COUNT_SET_2" },
+ { 8451, "MPL_AUX_PERF_COUNT_SET_3" },
+ { 8452, "MPL_AUX_PERF_COUNT" },
+ { 8453, "AUX_PERF_COUNT_0" },
+ { 8454, "AUX_PERF_COUNT_1" },
+ { 8455, "AUX_PERF_COUNT_CTL" },
+ { 8456, "AUX_PERF_COUNT_STS" },
+ { 8704, "MPL_INTCTRL_3_SET_0" },
+ { 8705, "MPL_INTCTRL_3_SET_1" },
+ { 8706, "MPL_INTCTRL_3_SET_2" },
+ { 8707, "MPL_INTCTRL_3_SET_3" },
+ { 8708, "MPL_INTCTRL_3" },
+ { 8709, "INTCTRL_3_STATUS" },
+ { 8710, "INTERRUPT_MASK_3" },
+ { 8711, "INTERRUPT_MASK_RESET_3" },
+ { 8712, "INTERRUPT_MASK_SET_3" },
+ { 8713, "INTERRUPT_VECTOR_BASE_3" },
+ { 8714, "SINGLE_STEP_EN_0_3" },
+ { 8715, "SINGLE_STEP_EN_1_3" },
+ { 8716, "SINGLE_STEP_EN_2_3" },
+ { 8717, "SINGLE_STEP_EN_3_3" },
+ { 8832, "EX_CONTEXT_3_0" },
+ { 8833, "EX_CONTEXT_3_1" },
+ { 8834, "SYSTEM_SAVE_3_0" },
+ { 8835, "SYSTEM_SAVE_3_1" },
+ { 8836, "SYSTEM_SAVE_3_2" },
+ { 8837, "SYSTEM_SAVE_3_3" },
+ { 8960, "MPL_INTCTRL_2_SET_0" },
+ { 8961, "MPL_INTCTRL_2_SET_1" },
+ { 8962, "MPL_INTCTRL_2_SET_2" },
+ { 8963, "MPL_INTCTRL_2_SET_3" },
+ { 8964, "MPL_INTCTRL_2" },
+ { 8965, "INTCTRL_2_STATUS" },
+ { 8966, "INTERRUPT_MASK_2" },
+ { 8967, "INTERRUPT_MASK_RESET_2" },
+ { 8968, "INTERRUPT_MASK_SET_2" },
+ { 8969, "INTERRUPT_VECTOR_BASE_2" },
+ { 8970, "SINGLE_STEP_EN_0_2" },
+ { 8971, "SINGLE_STEP_EN_1_2" },
+ { 8972, "SINGLE_STEP_EN_2_2" },
+ { 8973, "SINGLE_STEP_EN_3_2" },
+ { 9088, "EX_CONTEXT_2_0" },
+ { 9089, "EX_CONTEXT_2_1" },
+ { 9090, "SYSTEM_SAVE_2_0" },
+ { 9091, "SYSTEM_SAVE_2_1" },
+ { 9092, "SYSTEM_SAVE_2_2" },
+ { 9093, "SYSTEM_SAVE_2_3" },
+ { 9216, "MPL_INTCTRL_1_SET_0" },
+ { 9217, "MPL_INTCTRL_1_SET_1" },
+ { 9218, "MPL_INTCTRL_1_SET_2" },
+ { 9219, "MPL_INTCTRL_1_SET_3" },
+ { 9220, "MPL_INTCTRL_1" },
+ { 9221, "INTCTRL_1_STATUS" },
+ { 9222, "INTERRUPT_MASK_1" },
+ { 9223, "INTERRUPT_MASK_RESET_1" },
+ { 9224, "INTERRUPT_MASK_SET_1" },
+ { 9225, "INTERRUPT_VECTOR_BASE_1" },
+ { 9226, "SINGLE_STEP_EN_0_1" },
+ { 9227, "SINGLE_STEP_EN_1_1" },
+ { 9228, "SINGLE_STEP_EN_2_1" },
+ { 9229, "SINGLE_STEP_EN_3_1" },
+ { 9344, "EX_CONTEXT_1_0" },
+ { 9345, "EX_CONTEXT_1_1" },
+ { 9346, "SYSTEM_SAVE_1_0" },
+ { 9347, "SYSTEM_SAVE_1_1" },
+ { 9348, "SYSTEM_SAVE_1_2" },
+ { 9349, "SYSTEM_SAVE_1_3" },
+ { 9472, "MPL_INTCTRL_0_SET_0" },
+ { 9473, "MPL_INTCTRL_0_SET_1" },
+ { 9474, "MPL_INTCTRL_0_SET_2" },
+ { 9475, "MPL_INTCTRL_0_SET_3" },
+ { 9476, "MPL_INTCTRL_0" },
+ { 9477, "INTCTRL_0_STATUS" },
+ { 9478, "INTERRUPT_MASK_0" },
+ { 9479, "INTERRUPT_MASK_RESET_0" },
+ { 9480, "INTERRUPT_MASK_SET_0" },
+ { 9481, "INTERRUPT_VECTOR_BASE_0" },
+ { 9482, "SINGLE_STEP_EN_0_0" },
+ { 9483, "SINGLE_STEP_EN_1_0" },
+ { 9484, "SINGLE_STEP_EN_2_0" },
+ { 9485, "SINGLE_STEP_EN_3_0" },
+ { 9600, "EX_CONTEXT_0_0" },
+ { 9601, "EX_CONTEXT_0_1" },
+ { 9602, "SYSTEM_SAVE_0_0" },
+ { 9603, "SYSTEM_SAVE_0_1" },
+ { 9604, "SYSTEM_SAVE_0_2" },
+ { 9605, "SYSTEM_SAVE_0_3" },
+ { 9728, "MPL_BOOT_ACCESS_SET_0" },
+ { 9729, "MPL_BOOT_ACCESS_SET_1" },
+ { 9730, "MPL_BOOT_ACCESS_SET_2" },
+ { 9731, "MPL_BOOT_ACCESS_SET_3" },
+ { 9732, "MPL_BOOT_ACCESS" },
+ { 9733, "BIG_ENDIAN_CONFIG" },
+ { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" },
+ { 9735, "CACHE_INVALIDATION_MASK_0" },
+ { 9736, "CACHE_INVALIDATION_MASK_1" },
+ { 9737, "CACHE_INVALIDATION_MASK_2" },
+ { 9738, "CBOX_CACHEASRAM_CONFIG" },
+ { 9739, "CBOX_CACHE_CONFIG" },
+ { 9740, "CBOX_HOME_MAP_ADDR" },
+ { 9741, "CBOX_HOME_MAP_DATA" },
+ { 9742, "CBOX_MMAP_0" },
+ { 9743, "CBOX_MMAP_1" },
+ { 9744, "CBOX_MMAP_2" },
+ { 9745, "CBOX_MMAP_3" },
+ { 9746, "CBOX_MSR" },
+ { 9747, "DIAG_BCST_CTL" },
+ { 9748, "DIAG_BCST_MASK" },
+ { 9749, "DIAG_BCST_TRIGGER" },
+ { 9750, "DIAG_MUX_CTL" },
+ { 9751, "DIAG_TRACE_CTL" },
+ { 9752, "DIAG_TRACE_DATA" },
+ { 9753, "DIAG_TRACE_STS" },
+ { 9754, "IDN_DEMUX_BUF_THRESH" },
+ { 9755, "L1_I_PIN_WAY_0" },
+ { 9756, "MEM_ROUTE_ORDER" },
+ { 9757, "MEM_STRIPE_CONFIG" },
+ { 9758, "PERF_COUNT_PLS" },
+ { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" },
+ { 9760, "QUIESCE_CTL" },
+ { 9761, "RSHIM_COORD" },
+ { 9762, "SBOX_CONFIG" },
+ { 9763, "UDN_DEMUX_BUF_THRESH" },
+ { 9764, "XDN_CORE_STARVATION_COUNT" },
+ { 9765, "XDN_ROUND_ROBIN_ARB_CTL" },
+ { 9856, "CYCLE_MODIFY" },
+ { 9857, "I_AAR" },
+ { 9984, "MPL_WORLD_ACCESS_SET_0" },
+ { 9985, "MPL_WORLD_ACCESS_SET_1" },
+ { 9986, "MPL_WORLD_ACCESS_SET_2" },
+ { 9987, "MPL_WORLD_ACCESS_SET_3" },
+ { 9988, "MPL_WORLD_ACCESS" },
+ { 9989, "DONE" },
+ { 9990, "DSTREAM_PF" },
+ { 9991, "FAIL" },
+ { 9992, "INTERRUPT_CRITICAL_SECTION" },
+ { 9993, "PASS" },
+ { 9994, "PSEUDO_RANDOM_NUMBER" },
+ { 9995, "TILE_COORD" },
+ { 9996, "TILE_RTF_HWM" },
+ { 10112, "CMPEXCH_VALUE" },
+ { 10113, "CYCLE" },
+ { 10114, "EVENT_BEGIN" },
+ { 10115, "EVENT_END" },
+ { 10116, "PROC_STATUS" },
+ { 10117, "SIM_CONTROL" },
+ { 10118, "SIM_SOCKET" },
+ { 10119, "STATUS_SATURATE" },
+ { 10240, "MPL_I_ASID_SET_0" },
+ { 10241, "MPL_I_ASID_SET_1" },
+ { 10242, "MPL_I_ASID_SET_2" },
+ { 10243, "MPL_I_ASID_SET_3" },
+ { 10244, "MPL_I_ASID" },
+ { 10245, "I_ASID" },
+ { 10496, "MPL_D_ASID_SET_0" },
+ { 10497, "MPL_D_ASID_SET_1" },
+ { 10498, "MPL_D_ASID_SET_2" },
+ { 10499, "MPL_D_ASID_SET_3" },
+ { 10500, "MPL_D_ASID" },
+ { 10501, "D_ASID" },
+ { 10752, "MPL_DOUBLE_FAULT_SET_0" },
+ { 10753, "MPL_DOUBLE_FAULT_SET_1" },
+ { 10754, "MPL_DOUBLE_FAULT_SET_2" },
+ { 10755, "MPL_DOUBLE_FAULT_SET_3" },
+ { 10756, "MPL_DOUBLE_FAULT" },
+ { 10757, "LAST_INTERRUPT_REASON" },
+};
+
+const int tilegx_num_sprs = 441;
+
+const char *
+get_tilegx_spr_name (int num)
+{
+ void *result;
+ struct tilegx_spr key;
+
+ key.number = num;
+ result = bsearch((const void *) &key, (const void *) tilegx_sprs,
+ tilegx_num_sprs, sizeof (struct tilegx_spr),
+ tilegx_spr_compare);
+
+ if (result == NULL)
+ {
+ return (NULL);
+ }
+ else
+ {
+ struct tilegx_spr *result_ptr = (struct tilegx_spr *) result;
+ return (result_ptr->name);
+ }
+}
+
+int
+print_insn_tilegx (unsigned char * memaddr)
+{
+ struct tilegx_decoded_instruction
+ decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
+ unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES];
+ int i, num_instructions, num_printed;
+ tilegx_mnemonic padding_mnemonic;
+
+ memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES);
+
+ /* Parse the instructions in the bundle. */
+ num_instructions =
+ parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded);
+
+ /* Print the instructions in the bundle. */
+ printf("{ ");
+ num_printed = 0;
+
+ /* Determine which nop opcode is used for padding and should be skipped. */
+ padding_mnemonic = TILEGX_OPC_FNOP;
+ for (i = 0; i < num_instructions; i++)
+ {
+ if (!decoded[i].opcode->can_bundle)
+ {
+ /* Instructions that cannot be bundled are padded out with nops,
+ rather than fnops. Displaying them is always clutter. */
+ padding_mnemonic = TILEGX_OPC_NOP;
+ break;
+ }
+ }
+
+ for (i = 0; i < num_instructions; i++)
+ {
+ const struct tilegx_opcode *opcode = decoded[i].opcode;
+ const char *name;
+ int j;
+
+ /* Do not print out fnops, unless everything is an fnop, in
+ which case we will print out just the last one. */
+ if (opcode->mnemonic == padding_mnemonic
+ && (num_printed > 0 || i + 1 < num_instructions))
+ continue;
+
+ if (num_printed > 0)
+ printf(" ; ");
+ ++num_printed;
+
+ name = opcode->name;
+ if (name == NULL)
+ name = "<invalid>";
+ printf("%s", name);
+
+ for (j = 0; j < opcode->num_operands; j++)
+ {
+ unsigned long long num;
+ const struct tilegx_operand *op;
+ const char *spr_name;
+
+ if (j > 0)
+ printf (",");
+ printf (" ");
+
+ num = decoded[i].operand_values[j];
+
+ op = decoded[i].operands[j];
+ switch (op->type)
+ {
+ case TILEGX_OP_TYPE_REGISTER:
+ printf ("%s", tilegx_register_names[(int)num]);
+ break;
+ case TILEGX_OP_TYPE_SPR:
+ spr_name = get_tilegx_spr_name(num);
+ if (spr_name != NULL)
+ printf ("%s", spr_name);
+ else
+ printf ("%d", (int)num);
+ break;
+ case TILEGX_OP_TYPE_IMMEDIATE:
+ printf ("%d", (int)num);
+ break;
+ case TILEGX_OP_TYPE_ADDRESS:
+ printf ("0x%016llx", num);
+ break;
+ default:
+ abort ();
+ }
+ }
+ }
+ printf (" }\n");
+
+ return TILEGX_BUNDLE_SIZE_IN_BYTES;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c
new file mode 100644
index 0000000000..177a65b006
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c
@@ -0,0 +1,2563 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* TileGX architecture. */
+/* Contributed by Tilera Corporation. */
+#include "sljitNativeTILEGX-encoder.c"
+
+#define SIMM_8BIT_MAX (0x7f)
+#define SIMM_8BIT_MIN (-0x80)
+#define SIMM_16BIT_MAX (0x7fff)
+#define SIMM_16BIT_MIN (-0x8000)
+#define SIMM_17BIT_MAX (0xffff)
+#define SIMM_17BIT_MIN (-0x10000)
+#define SIMM_32BIT_MAX (0x7fffffff)
+#define SIMM_32BIT_MIN (-0x7fffffff - 1)
+#define SIMM_48BIT_MAX (0x7fffffff0000L)
+#define SIMM_48BIT_MIN (-0x800000000000L)
+#define IMM16(imm) ((imm) & 0xffff)
+
+#define UIMM_16BIT_MAX (0xffff)
+
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5)
+#define PIC_ADDR_REG TMP_REG2
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
+ 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7
+};
+
+#define SLJIT_LOCALS_REG_mapped 54
+#define TMP_REG1_mapped 5
+#define TMP_REG2_mapped 16
+#define TMP_REG3_mapped 6
+#define ADDR_TMP_mapped 7
+
+/* Flags are keept in volatile registers. */
+#define EQUAL_FLAG 8
+/* And carry flag as well. */
+#define ULESS_FLAG 9
+#define UGREATER_FLAG 10
+#define LESS_FLAG 11
+#define GREATER_FLAG 12
+#define OVERFLOW_FLAG 13
+
+#define ZERO 63
+#define RA 55
+#define TMP_EREG1 14
+#define TMP_EREG2 15
+
+#define LOAD_DATA 0x01
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x02
+#define HALF_DATA 0x04
+#define INT_DATA 0x06
+#define SIGNED_DATA 0x08
+#define DOUBLE_DATA 0x10
+
+/* Separates integer and floating point registers */
+#define GPR_REG 0xf
+
+#define MEM_MASK 0x1f
+
+#define WRITE_BACK 0x00020
+#define ARG_TEST 0x00040
+#define ALT_KEEP_CACHE 0x00080
+#define CUMULATIVE_OP 0x00100
+#define LOGICAL_OP 0x00200
+#define IMM_OP 0x00400
+#define SRC2_IMM 0x00800
+
+#define UNUSED_DEST 0x01000
+#define REG_DEST 0x02000
+#define REG1_SOURCE 0x04000
+#define REG2_SOURCE 0x08000
+#define SLOW_SRC1 0x10000
+#define SLOW_SRC2 0x20000
+#define SLOW_DEST 0x40000
+
+/* Only these flags are set. UNUSED_DEST is not set when no flags should be set.
+ */
+#define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
+
+SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void)
+{
+ return "TileGX" SLJIT_CPUINFO;
+}
+
+/* Length of an instruction word */
+typedef sljit_uw sljit_ins;
+
+struct jit_instr {
+ const struct tilegx_opcode* opcode;
+ tilegx_pipeline pipe;
+ unsigned long input_registers;
+ unsigned long output_registers;
+ int operand_value[4];
+ int line;
+};
+
+/* Opcode Helper Macros */
+#define TILEGX_X_MODE 0
+
+#define X_MODE create_Mode(TILEGX_X_MODE)
+
+#define FNOP_X0 \
+ create_Opcode_X0(RRR_0_OPCODE_X0) | \
+ create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
+ create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0)
+
+#define FNOP_X1 \
+ create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
+ create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1)
+
+#define NOP \
+ create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1
+
+#define ANOP_X0 \
+ create_Opcode_X0(RRR_0_OPCODE_X0) | \
+ create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
+ create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0)
+
+#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
+ create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \
+ create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0
+
+#define ADD_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define ADDI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
+ create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0
+
+#define SUB_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define NOR_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define OR_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define AND_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define XOR_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define CMOVNEZ_X0 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
+ create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1
+
+#define CMOVEQZ_X0 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
+ create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1
+
+#define ADDLI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0
+
+#define V4INT_L_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define BFEXTU_X0 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
+ create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1
+
+#define BFEXTS_X0 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
+ create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1
+
+#define SHL16INSLI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0
+
+#define ST_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0
+
+#define LD_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
+ create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0
+
+#define JR_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
+ create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0
+
+#define JALR_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
+ create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0
+
+#define CLZ_X0 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
+ create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
+ create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1
+
+#define CMPLTUI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
+ create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0
+
+#define CMPLTU_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define CMPLTS_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define XORI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
+ create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0
+
+#define ORI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
+ create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0
+
+#define ANDI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
+ create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0
+
+#define SHLI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
+ create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0
+
+#define SHL_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define SHRSI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
+ create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0
+
+#define SHRS_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define SHRUI_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
+ create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0
+
+#define SHRU_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
+ create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0
+
+#define BEQZ_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
+ create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0
+
+#define BNEZ_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
+ create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0
+
+#define J_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
+ create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0
+
+#define JAL_X1 \
+ create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
+ create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0
+
+#define DEST_X0(x) create_Dest_X0(x)
+#define SRCA_X0(x) create_SrcA_X0(x)
+#define SRCB_X0(x) create_SrcB_X0(x)
+#define DEST_X1(x) create_Dest_X1(x)
+#define SRCA_X1(x) create_SrcA_X1(x)
+#define SRCB_X1(x) create_SrcB_X1(x)
+#define IMM16_X1(x) create_Imm16_X1(x)
+#define IMM8_X1(x) create_Imm8_X1(x)
+#define BFSTART_X0(x) create_BFStart_X0(x)
+#define BFEND_X0(x) create_BFEnd_X0(x)
+#define SHIFTIMM_X1(x) create_ShAmt_X1(x)
+#define JOFF_X1(x) create_JumpOff_X1(x)
+#define BOFF_X1(x) create_BrOff_X1(x)
+
+static const tilegx_mnemonic data_transfer_insts[16] = {
+ /* u w s */ TILEGX_OPC_ST /* st */,
+ /* u w l */ TILEGX_OPC_LD /* ld */,
+ /* u b s */ TILEGX_OPC_ST1 /* st1 */,
+ /* u b l */ TILEGX_OPC_LD1U /* ld1u */,
+ /* u h s */ TILEGX_OPC_ST2 /* st2 */,
+ /* u h l */ TILEGX_OPC_LD2U /* ld2u */,
+ /* u i s */ TILEGX_OPC_ST4 /* st4 */,
+ /* u i l */ TILEGX_OPC_LD4U /* ld4u */,
+ /* s w s */ TILEGX_OPC_ST /* st */,
+ /* s w l */ TILEGX_OPC_LD /* ld */,
+ /* s b s */ TILEGX_OPC_ST1 /* st1 */,
+ /* s b l */ TILEGX_OPC_LD1S /* ld1s */,
+ /* s h s */ TILEGX_OPC_ST2 /* st2 */,
+ /* s h l */ TILEGX_OPC_LD2S /* ld2s */,
+ /* s i s */ TILEGX_OPC_ST4 /* st4 */,
+ /* s i l */ TILEGX_OPC_LD4S /* ld4s */,
+};
+
+#ifdef TILEGX_JIT_DEBUG
+static sljit_s32 push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line)
+{
+ sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ printf("|%04d|S0|:\t\t", line);
+ print_insn_tilegx(ptr);
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins)
+{
+ sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+#define push_inst(a, b) push_inst_debug(a, b, __LINE__)
+#else
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
+{
+ sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+#endif
+
+#define BUNDLE_FORMAT_MASK(p0, p1, p2) \
+ ((p0) | ((p1) << 8) | ((p2) << 16))
+
+#define BUNDLE_FORMAT(p0, p1, p2) \
+ { \
+ { \
+ (tilegx_pipeline)(p0), \
+ (tilegx_pipeline)(p1), \
+ (tilegx_pipeline)(p2) \
+ }, \
+ BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \
+ }
+
+#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS
+
+#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
+
+#define PI(encoding) \
+ push_inst(compiler, encoding)
+
+#define PB3(opcode, dst, srca, srcb) \
+ push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__)
+
+#define PB2(opcode, dst, src) \
+ push_2_buffer(compiler, opcode, dst, src, __LINE__)
+
+#define JR(reg) \
+ push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__)
+
+#define ADD(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__)
+
+#define SUB(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__)
+
+#define MUL(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__)
+
+#define NOR(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__)
+
+#define OR(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__)
+
+#define XOR(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__)
+
+#define AND(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__)
+
+#define CLZ(dst, src) \
+ push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__)
+
+#define SHLI(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__)
+
+#define SHRUI(dst, srca, imm) \
+ push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__)
+
+#define XORI(dst, srca, imm) \
+ push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__)
+
+#define ORI(dst, srca, imm) \
+ push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__)
+
+#define CMPLTU(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__)
+
+#define CMPLTS(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__)
+
+#define CMPLTUI(dst, srca, imm) \
+ push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__)
+
+#define CMOVNEZ(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__)
+
+#define CMOVEQZ(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__)
+
+#define ADDLI(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__)
+
+#define SHL16INSLI(dst, srca, srcb) \
+ push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__)
+
+#define LD_ADD(dst, addr, adjust) \
+ push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__)
+
+#define ST_ADD(src, addr, adjust) \
+ push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__)
+
+#define LD(dst, addr) \
+ push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__)
+
+#define BFEXTU(dst, src, start, end) \
+ push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__)
+
+#define BFEXTS(dst, src, start, end) \
+ push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__)
+
+#define ADD_SOLO(dest, srca, srcb) \
+ push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb))
+
+#define ADDI_SOLO(dest, srca, imm) \
+ push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm))
+
+#define ADDLI_SOLO(dest, srca, imm) \
+ push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
+
+#define SHL16INSLI_SOLO(dest, srca, imm) \
+ push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
+
+#define JALR_SOLO(reg) \
+ push_inst(compiler, JALR_X1 | SRCA_X1(reg))
+
+#define JR_SOLO(reg) \
+ push_inst(compiler, JR_X1 | SRCA_X1(reg))
+
+struct Format {
+ /* Mapping of bundle issue slot to assigned pipe. */
+ tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
+
+ /* Mask of pipes used by this bundle. */
+ unsigned int pipe_mask;
+};
+
+const struct Format formats[] =
+{
+ /* In Y format we must always have something in Y2, since it has
+ * no fnop, so this conveys that Y2 must always be used. */
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE),
+
+ /* Y format has three instructions. */
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0),
+
+ /* X format has only two instructions. */
+ BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE),
+ BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE)
+};
+
+
+struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
+unsigned long inst_buf_index;
+
+tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode)
+{
+ /* FIXME: tile: we could pregenerate this. */
+ int pipe;
+ for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++)
+ ;
+ return (tilegx_pipeline)(pipe);
+}
+
+void insert_nop(tilegx_mnemonic opc, int line)
+{
+ const struct tilegx_opcode* opcode = NULL;
+
+ memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]);
+
+ opcode = &tilegx_opcodes[opc];
+ inst_buf[0].opcode = opcode;
+ inst_buf[0].pipe = get_any_valid_pipe(opcode);
+ inst_buf[0].input_registers = 0;
+ inst_buf[0].output_registers = 0;
+ inst_buf[0].line = line;
+ ++inst_buf_index;
+}
+
+const struct Format* compute_format()
+{
+ unsigned int compatible_pipes = BUNDLE_FORMAT_MASK(
+ inst_buf[0].opcode->pipes,
+ inst_buf[1].opcode->pipes,
+ (inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE)));
+
+ const struct Format* match = NULL;
+ const struct Format *b = NULL;
+ unsigned int i;
+ for (i = 0; i < sizeof formats / sizeof formats[0]; i++) {
+ b = &formats[i];
+ if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) {
+ match = b;
+ break;
+ }
+ }
+
+ return match;
+}
+
+sljit_s32 assign_pipes()
+{
+ unsigned long output_registers = 0;
+ unsigned int i = 0;
+
+ if (inst_buf_index == 1) {
+ tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle
+ ? TILEGX_OPC_FNOP : TILEGX_OPC_NOP;
+ insert_nop(opc, __LINE__);
+ }
+
+ const struct Format* match = compute_format();
+
+ if (match == NULL)
+ return -1;
+
+ for (i = 0; i < inst_buf_index; i++) {
+
+ if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0))
+ return -1;
+
+ if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0))
+ return -1;
+
+ /* Don't include Rzero in the match set, to avoid triggering
+ needlessly on 'prefetch' instrs. */
+
+ output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL;
+
+ inst_buf[i].pipe = match->pipe[i];
+ }
+
+ /* If only 2 instrs, and in Y-mode, insert a nop. */
+ if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) {
+ insert_nop(TILEGX_OPC_FNOP, __LINE__);
+
+ /* Select the yet unassigned pipe. */
+ tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0
+ + TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2)
+ - (inst_buf[1].pipe + inst_buf[2].pipe)));
+
+ inst_buf[0].pipe = pipe;
+ }
+
+ return 0;
+}
+
+tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst)
+{
+ int i, val;
+ const struct tilegx_opcode* opcode = inst->opcode;
+ tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe];
+
+ const struct tilegx_operand* operand = NULL;
+ for (i = 0; i < opcode->num_operands; i++) {
+ operand = &tilegx_operands[opcode->operands[inst->pipe][i]];
+ val = inst->operand_value[i];
+
+ bits |= operand->insert(val);
+ }
+
+ return bits;
+}
+
+static sljit_s32 update_buffer(struct sljit_compiler *compiler)
+{
+ int i;
+ int orig_index = inst_buf_index;
+ struct jit_instr inst0 = inst_buf[0];
+ struct jit_instr inst1 = inst_buf[1];
+ struct jit_instr inst2 = inst_buf[2];
+ tilegx_bundle_bits bits = 0;
+
+ /* If the bundle is valid as is, perform the encoding and return 1. */
+ if (assign_pipes() == 0) {
+ for (i = 0; i < inst_buf_index; i++) {
+ bits |= get_bundle_bit(inst_buf + i);
+#ifdef TILEGX_JIT_DEBUG
+ printf("|%04d", inst_buf[i].line);
+#endif
+ }
+#ifdef TILEGX_JIT_DEBUG
+ if (inst_buf_index == 3)
+ printf("|M0|:\t");
+ else
+ printf("|M0|:\t\t");
+ print_insn_tilegx(&bits);
+#endif
+
+ inst_buf_index = 0;
+
+#ifdef TILEGX_JIT_DEBUG
+ return push_inst_nodebug(compiler, bits);
+#else
+ return push_inst(compiler, bits);
+#endif
+ }
+
+ /* If the bundle is invalid, split it in two. First encode the first two
+ (or possibly 1) instructions, and then the last, separately. Note that
+ assign_pipes may have re-ordered the instrs (by inserting no-ops in
+ lower slots) so we need to reset them. */
+
+ inst_buf_index = orig_index - 1;
+ inst_buf[0] = inst0;
+ inst_buf[1] = inst1;
+ inst_buf[2] = inst2;
+ if (assign_pipes() == 0) {
+ for (i = 0; i < inst_buf_index; i++) {
+ bits |= get_bundle_bit(inst_buf + i);
+#ifdef TILEGX_JIT_DEBUG
+ printf("|%04d", inst_buf[i].line);
+#endif
+ }
+
+#ifdef TILEGX_JIT_DEBUG
+ if (inst_buf_index == 3)
+ printf("|M1|:\t");
+ else
+ printf("|M1|:\t\t");
+ print_insn_tilegx(&bits);
+#endif
+
+ if ((orig_index - 1) == 2) {
+ inst_buf[0] = inst2;
+ inst_buf_index = 1;
+ } else if ((orig_index - 1) == 1) {
+ inst_buf[0] = inst1;
+ inst_buf_index = 1;
+ } else
+ SLJIT_ASSERT_STOP();
+
+#ifdef TILEGX_JIT_DEBUG
+ return push_inst_nodebug(compiler, bits);
+#else
+ return push_inst(compiler, bits);
+#endif
+ } else {
+ /* We had 3 instrs of which the first 2 can't live in the same bundle.
+ Split those two. Note that we don't try to then combine the second
+ and third instr into a single bundle. First instruction: */
+ inst_buf_index = 1;
+ inst_buf[0] = inst0;
+ inst_buf[1] = inst1;
+ inst_buf[2] = inst2;
+ if (assign_pipes() == 0) {
+ for (i = 0; i < inst_buf_index; i++) {
+ bits |= get_bundle_bit(inst_buf + i);
+#ifdef TILEGX_JIT_DEBUG
+ printf("|%04d", inst_buf[i].line);
+#endif
+ }
+
+#ifdef TILEGX_JIT_DEBUG
+ if (inst_buf_index == 3)
+ printf("|M2|:\t");
+ else
+ printf("|M2|:\t\t");
+ print_insn_tilegx(&bits);
+#endif
+
+ inst_buf[0] = inst1;
+ inst_buf[1] = inst2;
+ inst_buf_index = orig_index - 1;
+#ifdef TILEGX_JIT_DEBUG
+ return push_inst_nodebug(compiler, bits);
+#else
+ return push_inst(compiler, bits);
+#endif
+ } else
+ SLJIT_ASSERT_STOP();
+ }
+
+ SLJIT_ASSERT_STOP();
+}
+
+static sljit_s32 flush_buffer(struct sljit_compiler *compiler)
+{
+ while (inst_buf_index != 0) {
+ FAIL_IF(update_buffer(compiler));
+ }
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line)
+{
+ if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
+ FAIL_IF(update_buffer(compiler));
+
+ const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
+ inst_buf[inst_buf_index].opcode = opcode;
+ inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
+ inst_buf[inst_buf_index].operand_value[0] = op0;
+ inst_buf[inst_buf_index].operand_value[1] = op1;
+ inst_buf[inst_buf_index].operand_value[2] = op2;
+ inst_buf[inst_buf_index].operand_value[3] = op3;
+ inst_buf[inst_buf_index].input_registers = 1L << op1;
+ inst_buf[inst_buf_index].output_registers = 1L << op0;
+ inst_buf[inst_buf_index].line = line;
+ inst_buf_index++;
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line)
+{
+ if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
+ FAIL_IF(update_buffer(compiler));
+
+ const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
+ inst_buf[inst_buf_index].opcode = opcode;
+ inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
+ inst_buf[inst_buf_index].operand_value[0] = op0;
+ inst_buf[inst_buf_index].operand_value[1] = op1;
+ inst_buf[inst_buf_index].operand_value[2] = op2;
+ inst_buf[inst_buf_index].line = line;
+
+ switch (opc) {
+ case TILEGX_OPC_ST_ADD:
+ inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
+ inst_buf[inst_buf_index].output_registers = 1L << op0;
+ break;
+ case TILEGX_OPC_LD_ADD:
+ inst_buf[inst_buf_index].input_registers = 1L << op1;
+ inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1);
+ break;
+ case TILEGX_OPC_ADD:
+ case TILEGX_OPC_AND:
+ case TILEGX_OPC_SUB:
+ case TILEGX_OPC_MULX:
+ case TILEGX_OPC_OR:
+ case TILEGX_OPC_XOR:
+ case TILEGX_OPC_NOR:
+ case TILEGX_OPC_SHL:
+ case TILEGX_OPC_SHRU:
+ case TILEGX_OPC_SHRS:
+ case TILEGX_OPC_CMPLTU:
+ case TILEGX_OPC_CMPLTS:
+ case TILEGX_OPC_CMOVEQZ:
+ case TILEGX_OPC_CMOVNEZ:
+ inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2);
+ inst_buf[inst_buf_index].output_registers = 1L << op0;
+ break;
+ case TILEGX_OPC_ADDLI:
+ case TILEGX_OPC_XORI:
+ case TILEGX_OPC_ORI:
+ case TILEGX_OPC_SHLI:
+ case TILEGX_OPC_SHRUI:
+ case TILEGX_OPC_SHRSI:
+ case TILEGX_OPC_SHL16INSLI:
+ case TILEGX_OPC_CMPLTUI:
+ case TILEGX_OPC_CMPLTSI:
+ inst_buf[inst_buf_index].input_registers = 1L << op1;
+ inst_buf[inst_buf_index].output_registers = 1L << op0;
+ break;
+ default:
+ printf("unrecoginzed opc: %s\n", opcode->name);
+ SLJIT_ASSERT_STOP();
+ }
+
+ inst_buf_index++;
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line)
+{
+ if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
+ FAIL_IF(update_buffer(compiler));
+
+ const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
+ inst_buf[inst_buf_index].opcode = opcode;
+ inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
+ inst_buf[inst_buf_index].operand_value[0] = op0;
+ inst_buf[inst_buf_index].operand_value[1] = op1;
+ inst_buf[inst_buf_index].line = line;
+
+ switch (opc) {
+ case TILEGX_OPC_BEQZ:
+ case TILEGX_OPC_BNEZ:
+ inst_buf[inst_buf_index].input_registers = 1L << op0;
+ break;
+ case TILEGX_OPC_ST:
+ case TILEGX_OPC_ST1:
+ case TILEGX_OPC_ST2:
+ case TILEGX_OPC_ST4:
+ inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
+ inst_buf[inst_buf_index].output_registers = 0;
+ break;
+ case TILEGX_OPC_CLZ:
+ case TILEGX_OPC_LD:
+ case TILEGX_OPC_LD1U:
+ case TILEGX_OPC_LD1S:
+ case TILEGX_OPC_LD2U:
+ case TILEGX_OPC_LD2S:
+ case TILEGX_OPC_LD4U:
+ case TILEGX_OPC_LD4S:
+ inst_buf[inst_buf_index].input_registers = 1L << op1;
+ inst_buf[inst_buf_index].output_registers = 1L << op0;
+ break;
+ default:
+ printf("unrecoginzed opc: %s\n", opcode->name);
+ SLJIT_ASSERT_STOP();
+ }
+
+ inst_buf_index++;
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line)
+{
+ if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
+ FAIL_IF(update_buffer(compiler));
+
+ const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
+ inst_buf[inst_buf_index].opcode = opcode;
+ inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
+ inst_buf[inst_buf_index].input_registers = 0;
+ inst_buf[inst_buf_index].output_registers = 0;
+ inst_buf[inst_buf_index].line = line;
+ inst_buf_index++;
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line)
+{
+ if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
+ FAIL_IF(update_buffer(compiler));
+
+ const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
+ inst_buf[inst_buf_index].opcode = opcode;
+ inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
+ inst_buf[inst_buf_index].operand_value[0] = op0;
+ inst_buf[inst_buf_index].input_registers = 1L << op0;
+ inst_buf[inst_buf_index].output_registers = 0;
+ inst_buf[inst_buf_index].line = line;
+ inst_buf_index++;
+
+ return flush_buffer(compiler);
+}
+
+static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+{
+ sljit_sw diff;
+ sljit_uw target_addr;
+ sljit_ins *inst;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return code_ptr;
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size);
+ }
+
+ inst = (sljit_ins *)jump->addr;
+ if (jump->flags & IS_COND)
+ inst--;
+
+ diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3;
+ if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) {
+ jump->flags |= PATCH_B;
+
+ if (!(jump->flags & IS_COND)) {
+ if (jump->flags & IS_JAL) {
+ jump->flags &= ~(PATCH_B);
+ jump->flags |= PATCH_J;
+ inst[0] = JAL_X1;
+
+#ifdef TILEGX_JIT_DEBUG
+ printf("[runtime relocate]%04d:\t", __LINE__);
+ print_insn_tilegx(inst);
+#endif
+ } else {
+ inst[0] = BEQZ_X1 | SRCA_X1(ZERO);
+
+#ifdef TILEGX_JIT_DEBUG
+ printf("[runtime relocate]%04d:\t", __LINE__);
+ print_insn_tilegx(inst);
+#endif
+ }
+
+ return inst;
+ }
+
+ inst[0] = inst[0] ^ (0x7L << 55);
+
+#ifdef TILEGX_JIT_DEBUG
+ printf("[runtime relocate]%04d:\t", __LINE__);
+ print_insn_tilegx(inst);
+#endif
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+
+ if (jump->flags & IS_COND) {
+ if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
+ jump->flags |= PATCH_J;
+ inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2);
+ inst[1] = J_X1;
+ return inst + 1;
+ }
+
+ return code_ptr;
+ }
+
+ if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
+ jump->flags |= PATCH_J;
+
+ if (jump->flags & IS_JAL) {
+ inst[0] = JAL_X1;
+
+#ifdef TILEGX_JIT_DEBUG
+ printf("[runtime relocate]%04d:\t", __LINE__);
+ print_insn_tilegx(inst);
+#endif
+
+ } else {
+ inst[0] = J_X1;
+
+#ifdef TILEGX_JIT_DEBUG
+ printf("[runtime relocate]%04d:\t", __LINE__);
+ print_insn_tilegx(inst);
+#endif
+ }
+
+ return inst;
+ }
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ do {
+ buf_ptr = (sljit_ins *)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 3);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw) code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ if (jump && jump->addr == word_count) {
+ if (jump->flags & IS_JAL)
+ jump->addr = (sljit_uw)(code_ptr - 4);
+ else
+ jump->addr = (sljit_uw)(code_ptr - 3);
+
+ code_ptr = detect_jump_type(jump, code_ptr, code);
+ jump = jump->next;
+ }
+
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw) code_ptr;
+ const_ = const_->next;
+ }
+
+ code_ptr++;
+ word_count++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw) code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins *)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ addr = (sljit_sw)(addr - (jump->addr)) >> 3;
+ SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN);
+ buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr);
+
+#ifdef TILEGX_JIT_DEBUG
+ printf("[runtime relocate]%04d:\t", __LINE__);
+ print_insn_tilegx(buf_ptr);
+#endif
+ break;
+ }
+
+ if (jump->flags & PATCH_J) {
+ SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL));
+ addr = (sljit_sw)(addr - (jump->addr)) >> 3;
+ buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr);
+
+#ifdef TILEGX_JIT_DEBUG
+ printf("[runtime relocate]%04d:\t", __LINE__);
+ print_insn_tilegx(buf_ptr);
+#endif
+ break;
+ }
+
+ SLJIT_ASSERT(!(jump->flags & IS_JAL));
+
+ /* Set the fields of immediate loads. */
+ buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43);
+ buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43);
+ buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43);
+ } while (0);
+
+ jump = jump->next;
+ }
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ return code;
+}
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
+{
+
+ if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN)
+ return ADDLI(dst_ar, ZERO, imm);
+
+ if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) {
+ FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16));
+ return SHL16INSLI(dst_ar, dst_ar, imm);
+ }
+
+ if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) {
+ FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
+ FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
+ return SHL16INSLI(dst_ar, dst_ar, imm);
+ }
+
+ FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48));
+ FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32));
+ FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
+ return SHL16INSLI(dst_ar, dst_ar, imm);
+}
+
+static sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)
+{
+ /* Should *not* be optimized as load_immediate, as pcre relocation
+ mechanism will match this fixed 4-instruction pattern. */
+ if (flush) {
+ FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32));
+ FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16));
+ return SHL16INSLI_SOLO(dst_ar, dst_ar, imm);
+ }
+
+ FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
+ FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
+ return SHL16INSLI(dst_ar, dst_ar, imm);
+}
+
+static sljit_s32 emit_const_64(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)
+{
+ /* Should *not* be optimized as load_immediate, as pcre relocation
+ mechanism will match this fixed 4-instruction pattern. */
+ if (flush) {
+ FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48));
+ FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
+ FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
+ return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm);
+ }
+
+ FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48));
+ FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
+ FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
+ return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_ins base;
+ sljit_s32 i, tmp;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
+ local_size = (local_size + 7) & ~7;
+ compiler->local_size = local_size;
+
+ if (local_size <= SIMM_16BIT_MAX) {
+ /* Frequent case. */
+ FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size));
+ base = SLJIT_LOCALS_REG_mapped;
+ } else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
+ FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO));
+ FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
+ base = TMP_REG2_mapped;
+ local_size = 0;
+ }
+
+ /* Save the return address. */
+ FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
+ FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8));
+
+ /* Save the S registers. */
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--) {
+ FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
+ }
+
+ /* Save the R registers that need to be reserved. */
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
+ FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
+ }
+
+ /* Move the arguments to S registers. */
+ for (i = 0; i < args; i++) {
+ FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
+ compiler->local_size = (local_size + 7) & ~7;
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 local_size;
+ sljit_ins base;
+ sljit_s32 i, tmp;
+ sljit_s32 saveds;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ local_size = compiler->local_size;
+ if (local_size <= SIMM_16BIT_MAX)
+ base = SLJIT_LOCALS_REG_mapped;
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
+ FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
+ base = TMP_REG1_mapped;
+ local_size = 0;
+ }
+
+ /* Restore the return address. */
+ FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
+ FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8));
+
+ /* Restore the S registers. */
+ saveds = compiler->saveds;
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--) {
+ FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
+ }
+
+ /* Restore the R registers that need to be reserved. */
+ for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
+ FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
+ }
+
+ if (compiler->local_size <= SIMM_16BIT_MAX)
+ FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size));
+ else
+ FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO));
+
+ return JR(RA);
+}
+
+/* reg_ar is an absoulute register! */
+
+/* Can perform an operation using at most 1 instruction. */
+static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if ((!(flags & WRITE_BACK) || !(arg & REG_MASK))
+ && !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
+ /* Works for both absoulte and relative addresses. */
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw));
+
+ if (flags & LOAD_DATA)
+ FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
+ else
+ FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
+
+ return -1;
+ }
+
+ return 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
+
+ /* Simple operation except for updates. */
+ if (arg & OFFS_REG_MASK) {
+ argw &= 0x3;
+ next_argw &= 0x3;
+ if (argw && argw == next_argw
+ && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
+ return 1;
+ return 0;
+ }
+
+ if (arg == next_arg) {
+ if (((next_argw - argw) <= SIMM_16BIT_MAX
+ && (next_argw - argw) >= SIMM_16BIT_MIN))
+ return 1;
+
+ return 0;
+ }
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
+{
+ sljit_s32 tmp_ar, base;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))
+ tmp_ar = reg_ar;
+ else
+ tmp_ar = TMP_REG1_mapped;
+
+ base = arg & REG_MASK;
+
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
+ argw &= 0x3;
+
+ if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar);
+ FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
+ reg_ar = TMP_REG1_mapped;
+ }
+
+ /* Using the cache. */
+ if (argw == compiler->cache_argw) {
+ if (!(flags & WRITE_BACK)) {
+ if (arg == compiler->cache_arg) {
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
+ }
+
+ if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped));
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
+ }
+
+ FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped));
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
+ }
+ } else {
+ if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
+ FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
+ }
+ }
+ }
+
+ if (SLJIT_UNLIKELY(argw)) {
+ compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
+ compiler->cache_argw = argw;
+ FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw));
+ }
+
+ if (!(flags & WRITE_BACK)) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
+ tmp_ar = TMP_REG3_mapped;
+ } else
+ FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
+
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
+ }
+
+ FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
+
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
+ }
+
+ if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
+ /* Update only applies if a base register exists. */
+ if (reg_ar == reg_map[base]) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar);
+ if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
+ FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw));
+ if (flags & LOAD_DATA)
+ FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
+ else
+ FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
+
+ if (argw)
+ return ADDLI(reg_map[base], reg_map[base], argw);
+
+ return SLJIT_SUCCESS;
+ }
+
+ FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
+ reg_ar = TMP_REG1_mapped;
+ }
+
+ if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
+ if (argw)
+ FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw));
+ } else {
+ if (compiler->cache_arg == SLJIT_MEM
+ && argw - compiler->cache_argw <= SIMM_16BIT_MAX
+ && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
+ compiler->cache_argw = argw;
+ }
+
+ FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
+ } else {
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
+ FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
+ }
+ }
+
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
+ }
+
+ if (compiler->cache_arg == arg
+ && argw - compiler->cache_argw <= SIMM_16BIT_MAX
+ && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
+ compiler->cache_argw = argw;
+ }
+
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM
+ && argw - compiler->cache_argw <= SIMM_16BIT_MAX
+ && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
+ if (argw != compiler->cache_argw)
+ FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
+ } else {
+ compiler->cache_arg = SLJIT_MEM;
+ FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
+ }
+
+ compiler->cache_argw = argw;
+
+ if (!base) {
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
+ }
+
+ if (arg == next_arg
+ && next_argw - argw <= SIMM_16BIT_MAX
+ && next_argw - argw >= SIMM_16BIT_MIN) {
+ compiler->cache_arg = arg;
+ FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base]));
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
+ }
+
+ FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base]));
+
+ if (flags & LOAD_DATA)
+ return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
+ else
+ return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
+{
+ if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
+ return compiler->error;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
+}
+
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ return compiler->error;
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ if (FAST_IS_REG(dst))
+ return ADD(reg_map[dst], RA, ZERO);
+
+ /* Memory. */
+ return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(ADD(RA, reg_map[src], ZERO));
+
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw));
+
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, RA, srcw));
+
+ return JR(RA);
+}
+
+static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
+{
+ sljit_s32 overflow_ra = 0;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (dst != src2)
+ return ADD(reg_map[dst], reg_map[src2], ZERO);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S32)
+ return BFEXTS(reg_map[dst], reg_map[src2], 0, 31);
+
+ return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
+ } else if (dst != src2) {
+ SLJIT_ASSERT(src2 == 0);
+ return ADD(reg_map[dst], reg_map[src2], ZERO);
+ }
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S8)
+ return BFEXTS(reg_map[dst], reg_map[src2], 0, 7);
+
+ return BFEXTU(reg_map[dst], reg_map[src2], 0, 7);
+ } else if (dst != src2) {
+ SLJIT_ASSERT(src2 == 0);
+ return ADD(reg_map[dst], reg_map[src2], ZERO);
+ }
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_S16)
+ return BFEXTS(reg_map[dst], reg_map[src2], 0, 15);
+
+ return BFEXTU(reg_map[dst], reg_map[src2], 0, 15);
+ } else if (dst != src2) {
+ SLJIT_ASSERT(src2 == 0);
+ return ADD(reg_map[dst], reg_map[src2], ZERO);
+ }
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2]));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2]));
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2]));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(CLZ(reg_map[dst], reg_map[src2]));
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ADD:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63));
+ if (src2 < 0)
+ FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
+ }
+
+ if (op & SLJIT_SET_E)
+ FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2));
+
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2));
+ else {
+ FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2));
+ FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG));
+ }
+ }
+
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
+
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63));
+
+ if (src2 < 0)
+ FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1));
+ }
+ } else {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
+ FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
+
+ if (src1 != dst)
+ overflow_ra = reg_map[src1];
+ else if (src2 != dst)
+ overflow_ra = reg_map[src2];
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+
+ if (op & SLJIT_SET_E)
+ FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2]));
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2]));
+
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2]));
+
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra));
+ FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
+ }
+ }
+
+ /* a + b >= a | b (otherwise, the carry should be set to 1). */
+ if (op & SLJIT_SET_C)
+ FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG));
+
+ if (op & SLJIT_SET_O)
+ return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ADDC:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2));
+ else {
+ FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2));
+ FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1));
+ }
+ }
+
+ FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
+
+ } else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2]));
+
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2]));
+ }
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1));
+
+ FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG));
+
+ if (!(op & SLJIT_SET_C))
+ return SLJIT_SUCCESS;
+
+ /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
+ FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1));
+ FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG));
+ /* Set carry flag. */
+ return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1);
+
+ case SLJIT_SUB:
+ if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) {
+ FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63));
+
+ if (src2 < 0)
+ FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
+
+ if (src1 != dst)
+ overflow_ra = reg_map[src1];
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+
+ if (op & SLJIT_SET_E)
+ FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2));
+
+ if (op & SLJIT_SET_C) {
+ FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2));
+ FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped));
+ }
+
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
+
+ } else {
+
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
+ FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
+
+ if (src1 != dst)
+ overflow_ra = reg_map[src1];
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+
+ if (op & SLJIT_SET_E)
+ FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2]));
+
+ if (op & (SLJIT_SET_U | SLJIT_SET_C))
+ FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2]));
+
+ if (op & SLJIT_SET_U)
+ FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1]));
+
+ if (op & SLJIT_SET_S) {
+ FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2]));
+ FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1]));
+ }
+
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
+ FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
+ }
+
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra));
+ FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
+ return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
+ }
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_SUBC:
+ if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) {
+ FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C) {
+ FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2));
+ FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped));
+ }
+
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
+
+ } else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2]));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
+ }
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG));
+
+ FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG));
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO));
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MUL:
+ if (flags & SRC2_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2]));
+
+ return SLJIT_SUCCESS;
+
+#define EMIT_LOGICAL(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
+ ADDR_TMP_mapped, __LINE__)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_norm, reg_map[dst], reg_map[src1], \
+ ADDR_TMP_mapped, __LINE__)); \
+ } else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
+ reg_map[src2], __LINE__)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_norm, reg_map[dst], reg_map[src1], \
+ reg_map[src2], __LINE__)); \
+ }
+
+ case SLJIT_AND:
+ EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_OR:
+ EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_XOR:
+ EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR);
+ return SLJIT_SUCCESS;
+
+#define EMIT_SHIFT(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_imm, EQUAL_FLAG, reg_map[src1], \
+ src2 & 0x3F, __LINE__)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_imm, reg_map[dst], reg_map[src1], \
+ src2 & 0x3F, __LINE__)); \
+ } else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
+ reg_map[src2], __LINE__)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_3_buffer( \
+ compiler, op_norm, reg_map[dst], reg_map[src1], \
+ reg_map[src2], __LINE__)); \
+ }
+
+ case SLJIT_SHL:
+ EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS);
+ return SLJIT_SUCCESS;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg.
+ arg2 goes to TMP_REG2, imm or src reg.
+ TMP_REG3 can be used for caching.
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ sljit_s32 dst_r = TMP_REG2;
+ sljit_s32 src1_r;
+ sljit_sw src2_r = 0;
+ sljit_s32 sugg_src2_r = TMP_REG2;
+
+ if (!(flags & ALT_KEEP_CACHE)) {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ }
+
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ if (GET_FLAGS(op))
+ flags |= UNUSED_DEST;
+ } else if (FAST_IS_REG(dst)) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ sugg_src2_r = dst_r;
+ } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (flags & IMM_OP) {
+ if ((src2 & SLJIT_IMM) && src2w) {
+ if ((!(flags & LOGICAL_OP)
+ && (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN))
+ || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src2w;
+ }
+ }
+
+ if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
+ if ((!(flags & LOGICAL_OP)
+ && (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN))
+ || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src1w;
+
+ /* And swap arguments. */
+ src1 = src2;
+ src1w = src2w;
+ src2 = SLJIT_IMM;
+ /* src2w = src2_r unneeded. */
+ }
+ }
+ }
+
+ /* Source 1. */
+ if (FAST_IS_REG(src1)) {
+ src1_r = src1;
+ flags |= REG1_SOURCE;
+ } else if (src1 & SLJIT_IMM) {
+ if (src1w) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w));
+ src1_r = TMP_REG1;
+ } else
+ src1_r = 0;
+ } else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ src1_r = TMP_REG1;
+ }
+
+ /* Source 2. */
+ if (FAST_IS_REG(src2)) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+ dst_r = src2_r;
+ } else if (src2 & SLJIT_IMM) {
+ if (!(flags & SRC2_IMM)) {
+ if (src2w) {
+ FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w));
+ src2_r = sugg_src2_r;
+ } else {
+ src2_r = 0;
+ if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
+ dst_r = 0;
+ }
+ }
+ } else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ src2_r = sugg_src2_r;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ SLJIT_ASSERT(src2_r == TMP_REG2);
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
+ } else {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw));
+ }
+ } else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw));
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw);
+ return compiler->error;
+ }
+
+ return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw, sljit_s32 type)
+{
+ sljit_s32 sugg_dst_ar, dst_ar;
+ sljit_s32 flags = GET_ALL_FLAGS(op);
+ sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ op = GET_OPCODE(op);
+ if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32)
+ mem_type = INT_DATA | SIGNED_DATA;
+ sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2];
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
+ ADJUST_LOCAL_OFFSET(src, srcw);
+ FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ switch (type & 0xff) {
+ case SLJIT_EQUAL:
+ case SLJIT_NOT_EQUAL:
+ FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1));
+ dst_ar = sugg_dst_ar;
+ break;
+ case SLJIT_LESS:
+ case SLJIT_GREATER_EQUAL:
+ dst_ar = ULESS_FLAG;
+ break;
+ case SLJIT_GREATER:
+ case SLJIT_LESS_EQUAL:
+ dst_ar = UGREATER_FLAG;
+ break;
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_GREATER_EQUAL:
+ dst_ar = LESS_FLAG;
+ break;
+ case SLJIT_SIG_GREATER:
+ case SLJIT_SIG_LESS_EQUAL:
+ dst_ar = GREATER_FLAG;
+ break;
+ case SLJIT_OVERFLOW:
+ case SLJIT_NOT_OVERFLOW:
+ dst_ar = OVERFLOW_FLAG;
+ break;
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1));
+ dst_ar = sugg_dst_ar;
+ type ^= 0x1; /* Flip type bit for the XORI below. */
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ dst_ar = sugg_dst_ar;
+ break;
+ }
+
+ if (type & 0x1) {
+ FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1));
+ dst_ar = sugg_dst_ar;
+ }
+
+ if (op >= SLJIT_ADD) {
+ if (TMP_REG2_mapped != dst_ar)
+ FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO));
+ return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);
+
+ if (sugg_dst_ar != dst_ar)
+ return ADD(sugg_dst_ar, dst_ar, ZERO);
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) {
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_NOP:
+ return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__);
+
+ case SLJIT_BREAKPOINT:
+ return PI(BPT);
+
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+ SLJIT_ASSERT_STOP();
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_U32:
+ return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_S32:
+ return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw);
+
+ case SLJIT_MOV_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw);
+
+ case SLJIT_MOV_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw);
+
+ case SLJIT_MOV_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw);
+
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_P:
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_U32:
+ return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_S32:
+ return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_U8:
+ return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw);
+
+ case SLJIT_MOVU_S8:
+ return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw);
+
+ case SLJIT_MOVU_U16:
+ return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw);
+
+ case SLJIT_MOVU_S16:
+ return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
+
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+ return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+ if (src2 & SLJIT_IMM)
+ src2w &= 0x3f;
+ if (op & SLJIT_I32_OP)
+ src2w &= 0x1f;
+
+ return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ flush_buffer(compiler);
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 src_r = TMP_REG2;
+ struct sljit_jump *jump = NULL;
+
+ flush_buffer(compiler);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (FAST_IS_REG(src)) {
+ if (reg_map[src] != 0)
+ src_r = src;
+ else
+ FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO));
+ }
+
+ if (type >= SLJIT_CALL0) {
+ SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
+ if (src & (SLJIT_IMM | SLJIT_MEM)) {
+ if (src & SLJIT_IMM)
+ FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1));
+ else {
+ SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ }
+
+ FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
+
+ FAIL_IF(ADDI_SOLO(54, 54, -16));
+
+ FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG]));
+
+ return ADDI_SOLO(54, 54, 16);
+ }
+
+ /* Register input. */
+ if (type >= SLJIT_CALL1)
+ FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
+
+ FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO));
+
+ FAIL_IF(ADDI_SOLO(54, 54, -16));
+
+ FAIL_IF(JALR_SOLO(reg_map[src_r]));
+
+ return ADDI_SOLO(54, 54, 16);
+ }
+
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
+ jump->u.target = srcw;
+ FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
+
+ if (type >= SLJIT_FAST_CALL) {
+ FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO));
+ jump->addr = compiler->size;
+ FAIL_IF(JR_SOLO(reg_map[src_r]));
+ } else {
+ jump->addr = compiler->size;
+ FAIL_IF(JR_SOLO(reg_map[src_r]));
+ }
+
+ return SLJIT_SUCCESS;
+
+ } else if (src & SLJIT_MEM) {
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ flush_buffer(compiler);
+ }
+
+ FAIL_IF(JR_SOLO(reg_map[src_r]));
+
+ if (jump)
+ jump->addr = compiler->size;
+
+ return SLJIT_SUCCESS;
+}
+
+#define BR_Z(src) \
+ inst = BEQZ_X1 | SRCA_X1(src); \
+ flags = IS_COND;
+
+#define BR_NZ(src) \
+ inst = BNEZ_X1 | SRCA_X1(src); \
+ flags = IS_COND;
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ struct sljit_jump *jump;
+ sljit_ins inst;
+ sljit_s32 flags = 0;
+
+ flush_buffer(compiler);
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ switch (type) {
+ case SLJIT_EQUAL:
+ BR_NZ(EQUAL_FLAG);
+ break;
+ case SLJIT_NOT_EQUAL:
+ BR_Z(EQUAL_FLAG);
+ break;
+ case SLJIT_LESS:
+ BR_Z(ULESS_FLAG);
+ break;
+ case SLJIT_GREATER_EQUAL:
+ BR_NZ(ULESS_FLAG);
+ break;
+ case SLJIT_GREATER:
+ BR_Z(UGREATER_FLAG);
+ break;
+ case SLJIT_LESS_EQUAL:
+ BR_NZ(UGREATER_FLAG);
+ break;
+ case SLJIT_SIG_LESS:
+ BR_Z(LESS_FLAG);
+ break;
+ case SLJIT_SIG_GREATER_EQUAL:
+ BR_NZ(LESS_FLAG);
+ break;
+ case SLJIT_SIG_GREATER:
+ BR_Z(GREATER_FLAG);
+ break;
+ case SLJIT_SIG_LESS_EQUAL:
+ BR_NZ(GREATER_FLAG);
+ break;
+ case SLJIT_OVERFLOW:
+ case SLJIT_MUL_OVERFLOW:
+ BR_Z(OVERFLOW_FLAG);
+ break;
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ BR_NZ(OVERFLOW_FLAG);
+ break;
+ default:
+ /* Not conditional branch. */
+ inst = 0;
+ break;
+ }
+
+ jump->flags |= flags;
+
+ if (inst) {
+ inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6));
+ PTR_FAIL_IF(PI(inst));
+ }
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
+ if (type <= SLJIT_JUMP) {
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped));
+ } else {
+ SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
+ /* Cannot be optimized out if type is >= CALL0. */
+ jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
+ PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped));
+ }
+
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_const *const_;
+ sljit_s32 reg;
+
+ flush_buffer(compiler);
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_target >> 32) & 0xffff) << 43);
+ inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_target >> 16) & 0xffff) << 43);
+ inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_target & 0xffff) << 43);
+ SLJIT_CACHE_FLUSH(inst, inst + 3);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+{
+ sljit_ins *inst = (sljit_ins *)addr;
+
+ inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43);
+ inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43);
+ inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43);
+ inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43);
+ SLJIT_CACHE_FLUSH(inst, inst + 4);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
new file mode 100644
index 0000000000..00333f6b33
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
@@ -0,0 +1,550 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* x86 32-bit arch dependent functions. */
+
+static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm)
+{
+ sljit_u8 *inst;
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
+ FAIL_IF(!inst);
+ INC_SIZE(1 + sizeof(sljit_sw));
+ *inst++ = opcode;
+ sljit_unaligned_store_sw(inst, imm);
+ return SLJIT_SUCCESS;
+}
+
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset)
+{
+ if (type == SLJIT_JUMP) {
+ *code_ptr++ = JMP_i32;
+ jump->addr++;
+ }
+ else if (type >= SLJIT_FAST_CALL) {
+ *code_ptr++ = CALL_i32;
+ jump->addr++;
+ }
+ else {
+ *code_ptr++ = GROUP_0F;
+ *code_ptr++ = get_jump_code(type);
+ jump->addr += 2;
+ }
+
+ if (jump->flags & JUMP_LABEL)
+ jump->flags |= PATCH_MW;
+ else
+ sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset);
+ code_ptr += 4;
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 size;
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ compiler->args = args;
+ compiler->flags_saved = 0;
+
+ size = 1 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3);
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ size += (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
+#else
+ size += (args > 0 ? (2 + args * 3) : 0);
+#endif
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+
+ INC_SIZE(size);
+ PUSH_REG(reg_map[TMP_REG1]);
+#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (args > 0) {
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */;
+ }
+#endif
+ if (saveds > 2 || scratches > 7)
+ PUSH_REG(reg_map[SLJIT_S2]);
+ if (saveds > 1 || scratches > 8)
+ PUSH_REG(reg_map[SLJIT_S1]);
+ if (saveds > 0 || scratches > 9)
+ PUSH_REG(reg_map[SLJIT_S0]);
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (args > 0) {
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2];
+ }
+ if (args > 1) {
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1];
+ }
+ if (args > 2) {
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */;
+ *inst++ = 0x24;
+ *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
+ }
+#else
+ if (args > 0) {
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1];
+ *inst++ = sizeof(sljit_sw) * 2;
+ }
+ if (args > 1) {
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1];
+ *inst++ = sizeof(sljit_sw) * 3;
+ }
+ if (args > 2) {
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1];
+ *inst++ = sizeof(sljit_sw) * 4;
+ }
+#endif
+
+ SLJIT_COMPILE_ASSERT(SLJIT_LOCALS_OFFSET >= (2 + 4) * sizeof(sljit_uw), require_at_least_two_words);
+#if defined(__APPLE__)
+ /* Ignore pushed registers and SLJIT_LOCALS_OFFSET when computing the aligned local size. */
+ saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
+ local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
+#else
+ if (options & SLJIT_DOUBLE_ALIGNMENT) {
+ local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7);
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 17);
+ FAIL_IF(!inst);
+
+ INC_SIZE(17);
+ inst[0] = MOV_r_rm;
+ inst[1] = MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[SLJIT_SP];
+ inst[2] = GROUP_F7;
+ inst[3] = MOD_REG | (0 << 3) | reg_map[SLJIT_SP];
+ sljit_unaligned_store_sw(inst + 4, 0x4);
+ inst[8] = JNE_i8;
+ inst[9] = 6;
+ inst[10] = GROUP_BINARY_81;
+ inst[11] = MOD_REG | (5 << 3) | reg_map[SLJIT_SP];
+ sljit_unaligned_store_sw(inst + 12, 0x4);
+ inst[16] = PUSH_r + reg_map[TMP_REG1];
+ }
+ else
+ local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3);
+#endif
+
+ compiler->local_size = local_size;
+#ifdef _WIN32
+ if (local_size > 1024) {
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
+#else
+ local_size -= SLJIT_LOCALS_OFFSET;
+ FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
+ FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
+ SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, SLJIT_LOCALS_OFFSET));
+#endif
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
+ }
+#endif
+
+ SLJIT_ASSERT(local_size > 0);
+ return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
+ SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ compiler->args = args;
+
+#if defined(__APPLE__)
+ saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
+ compiler->local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
+#else
+ if (options & SLJIT_DOUBLE_ALIGNMENT)
+ compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7);
+ else
+ compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3);
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 size;
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+ SLJIT_ASSERT(compiler->args >= 0);
+
+ compiler->flags_saved = 0;
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ SLJIT_ASSERT(compiler->local_size > 0);
+ FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
+ SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
+
+#if !defined(__APPLE__)
+ if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
+ FAIL_IF(!inst);
+
+ INC_SIZE(3);
+ inst[0] = MOV_r_rm;
+ inst[1] = (reg_map[SLJIT_SP] << 3) | 0x4 /* SIB */;
+ inst[2] = (4 << 3) | reg_map[SLJIT_SP];
+ }
+#endif
+
+ size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) +
+ (compiler->saveds <= 3 ? compiler->saveds : 3);
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (compiler->args > 2)
+ size += 2;
+#else
+ if (compiler->args > 0)
+ size += 2;
+#endif
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+
+ INC_SIZE(size);
+
+ if (compiler->saveds > 0 || compiler->scratches > 9)
+ POP_REG(reg_map[SLJIT_S0]);
+ if (compiler->saveds > 1 || compiler->scratches > 8)
+ POP_REG(reg_map[SLJIT_S1]);
+ if (compiler->saveds > 2 || compiler->scratches > 7)
+ POP_REG(reg_map[SLJIT_S2]);
+ POP_REG(reg_map[TMP_REG1]);
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (compiler->args > 2)
+ RET_I16(sizeof(sljit_sw));
+ else
+ RET();
+#else
+ RET();
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* Size contains the flags as well. */
+static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size,
+ /* The register or immediate operand. */
+ sljit_s32 a, sljit_sw imma,
+ /* The general operand (not immediate). */
+ sljit_s32 b, sljit_sw immb)
+{
+ sljit_u8 *inst;
+ sljit_u8 *buf_ptr;
+ sljit_s32 flags = size & ~0xf;
+ sljit_s32 inst_size;
+
+ /* Both cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
+ /* Size flags not allowed for typed instructions. */
+ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
+ /* Both size flags cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
+ /* SSE2 and immediate is not possible. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
+ SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
+ && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
+ && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
+
+ size &= 0xf;
+ inst_size = size;
+
+ if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
+ inst_size++;
+ if (flags & EX86_PREF_66)
+ inst_size++;
+
+ /* Calculate size of b. */
+ inst_size += 1; /* mod r/m byte. */
+ if (b & SLJIT_MEM) {
+ if ((b & REG_MASK) == SLJIT_UNUSED)
+ inst_size += sizeof(sljit_sw);
+ else if (immb != 0 && !(b & OFFS_REG_MASK)) {
+ /* Immediate operand. */
+ if (immb <= 127 && immb >= -128)
+ inst_size += sizeof(sljit_s8);
+ else
+ inst_size += sizeof(sljit_sw);
+ }
+
+ if ((b & REG_MASK) == SLJIT_SP && !(b & OFFS_REG_MASK))
+ b |= TO_OFFS_REG(SLJIT_SP);
+
+ if ((b & OFFS_REG_MASK) != SLJIT_UNUSED)
+ inst_size += 1; /* SIB byte. */
+ }
+
+ /* Calculate size of a. */
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BIN_INS) {
+ if (imma <= 127 && imma >= -128) {
+ inst_size += 1;
+ flags |= EX86_BYTE_ARG;
+ } else
+ inst_size += 4;
+ }
+ else if (flags & EX86_SHIFT_INS) {
+ imma &= 0x1f;
+ if (imma != 1) {
+ inst_size ++;
+ flags |= EX86_BYTE_ARG;
+ }
+ } else if (flags & EX86_BYTE_ARG)
+ inst_size++;
+ else if (flags & EX86_HALF_ARG)
+ inst_size += sizeof(short);
+ else
+ inst_size += sizeof(sljit_sw);
+ }
+ else
+ SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);
+ PTR_FAIL_IF(!inst);
+
+ /* Encoding the byte. */
+ INC_SIZE(inst_size);
+ if (flags & EX86_PREF_F2)
+ *inst++ = 0xf2;
+ if (flags & EX86_PREF_F3)
+ *inst++ = 0xf3;
+ if (flags & EX86_PREF_66)
+ *inst++ = 0x66;
+
+ buf_ptr = inst + size;
+
+ /* Encode mod/rm byte. */
+ if (!(flags & EX86_SHIFT_INS)) {
+ if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
+ *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
+
+ if ((a & SLJIT_IMM) || (a == 0))
+ *buf_ptr = 0;
+ else if (!(flags & EX86_SSE2_OP1))
+ *buf_ptr = reg_map[a] << 3;
+ else
+ *buf_ptr = a << 3;
+ }
+ else {
+ if (a & SLJIT_IMM) {
+ if (imma == 1)
+ *inst = GROUP_SHIFT_1;
+ else
+ *inst = GROUP_SHIFT_N;
+ } else
+ *inst = GROUP_SHIFT_CL;
+ *buf_ptr = 0;
+ }
+
+ if (!(b & SLJIT_MEM))
+ *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_map[b] : b);
+ else if ((b & REG_MASK) != SLJIT_UNUSED) {
+ if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr |= 0x40;
+ else
+ *buf_ptr |= 0x80;
+ }
+
+ if ((b & OFFS_REG_MASK) == SLJIT_UNUSED)
+ *buf_ptr++ |= reg_map[b & REG_MASK];
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3);
+ }
+
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr++ = immb; /* 8 bit displacement. */
+ else {
+ sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_sw);
+ }
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3) | (immb << 6);
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x05;
+ sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_sw);
+ }
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BYTE_ARG)
+ *buf_ptr = imma;
+ else if (flags & EX86_HALF_ARG)
+ sljit_unaligned_store_s16(buf_ptr, imma);
+ else if (!(flags & EX86_SHIFT_INS))
+ sljit_unaligned_store_sw(buf_ptr, imma);
+ }
+
+ return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
+}
+
+/* --------------------------------------------------------------------- */
+/* Call / return instructions */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ sljit_u8 *inst;
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ inst = (sljit_u8*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
+
+ if (type >= SLJIT_CALL3)
+ PUSH_REG(reg_map[SLJIT_R2]);
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
+#else
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
+ FAIL_IF(!inst);
+ INC_SIZE(4 * (type - SLJIT_CALL0));
+
+ *inst++ = MOV_rm_r;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_R0] << 3) | 0x4 /* SIB */;
+ *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
+ *inst++ = 0;
+ if (type >= SLJIT_CALL2) {
+ *inst++ = MOV_rm_r;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_R1] << 3) | 0x4 /* SIB */;
+ *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
+ *inst++ = sizeof(sljit_sw);
+ }
+ if (type >= SLJIT_CALL3) {
+ *inst++ = MOV_rm_r;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_R2] << 3) | 0x4 /* SIB */;
+ *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
+ *inst++ = 2 * sizeof(sljit_sw);
+ }
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ dst = TMP_REG1;
+
+ if (FAST_IS_REG(dst)) {
+ /* Unused dest is possible here. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+
+ INC_SIZE(1);
+ POP_REG(reg_map[dst]);
+ return SLJIT_SUCCESS;
+ }
+
+ /* Memory. */
+ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst++ = POP_rm;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+ if (FAST_IS_REG(src)) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
+ FAIL_IF(!inst);
+
+ INC_SIZE(1 + 1);
+ PUSH_REG(reg_map[src]);
+ }
+ else if (src & SLJIT_MEM) {
+ inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_FF;
+ *inst |= PUSH_rm;
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ }
+ else {
+ /* SLJIT_IMM. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
+ FAIL_IF(!inst);
+
+ INC_SIZE(5 + 1);
+ *inst++ = PUSH_i32;
+ sljit_unaligned_store_sw(inst, srcw);
+ inst += sizeof(sljit_sw);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
new file mode 100644
index 0000000000..bc92d45680
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
@@ -0,0 +1,725 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* x86 64-bit arch dependent functions. */
+
+static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
+{
+ sljit_u8 *inst;
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
+ FAIL_IF(!inst);
+ INC_SIZE(2 + sizeof(sljit_sw));
+ *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
+ *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7);
+ sljit_unaligned_store_sw(inst, imm);
+ return SLJIT_SUCCESS;
+}
+
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
+{
+ if (type < SLJIT_JUMP) {
+ /* Invert type. */
+ *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
+ *code_ptr++ = 10 + 3;
+ }
+
+ SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
+ *code_ptr++ = REX_W | REX_B;
+ *code_ptr++ = MOV_r_i32 + 1;
+ jump->addr = (sljit_uw)code_ptr;
+
+ if (jump->flags & JUMP_LABEL)
+ jump->flags |= PATCH_MD;
+ else
+ sljit_unaligned_store_sw(code_ptr, jump->u.target);
+
+ code_ptr += sizeof(sljit_sw);
+ *code_ptr++ = REX_B;
+ *code_ptr++ = GROUP_FF;
+ *code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 i, tmp, size, saved_register_size;
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ compiler->flags_saved = 0;
+
+ /* Including the return address saved by the call instruction. */
+ saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
+
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = SLJIT_S0; i >= tmp; i--) {
+ size = reg_map[i] >= 8 ? 2 : 1;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+ if (reg_map[i] >= 8)
+ *inst++ = REX_B;
+ PUSH_REG(reg_lmap[i]);
+ }
+
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
+ size = reg_map[i] >= 8 ? 2 : 1;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+ if (reg_map[i] >= 8)
+ *inst++ = REX_B;
+ PUSH_REG(reg_lmap[i]);
+ }
+
+ if (args > 0) {
+ size = args * 3;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+
+ INC_SIZE(size);
+
+#ifndef _WIN64
+ if (args > 0) {
+ *inst++ = REX_W;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */;
+ }
+ if (args > 1) {
+ *inst++ = REX_W | REX_R;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */;
+ }
+ if (args > 2) {
+ *inst++ = REX_W | REX_R;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */;
+ }
+#else
+ if (args > 0) {
+ *inst++ = REX_W;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */;
+ }
+ if (args > 1) {
+ *inst++ = REX_W;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */;
+ }
+ if (args > 2) {
+ *inst++ = REX_W | REX_B;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */;
+ }
+#endif
+ }
+
+ local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size;
+ compiler->local_size = local_size;
+
+#ifdef _WIN64
+ if (local_size > 1024) {
+ /* Allocate stack for the callback, which grows the stack. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_s32)));
+ FAIL_IF(!inst);
+ INC_SIZE(4 + (3 + sizeof(sljit_s32)));
+ *inst++ = REX_W;
+ *inst++ = GROUP_BINARY_83;
+ *inst++ = MOD_REG | SUB | 4;
+ /* Allocated size for registers must be divisible by 8. */
+ SLJIT_ASSERT(!(saved_register_size & 0x7));
+ /* Aligned to 16 byte. */
+ if (saved_register_size & 0x8) {
+ *inst++ = 5 * sizeof(sljit_sw);
+ local_size -= 5 * sizeof(sljit_sw);
+ } else {
+ *inst++ = 4 * sizeof(sljit_sw);
+ local_size -= 4 * sizeof(sljit_sw);
+ }
+ /* Second instruction */
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] < 8, temporary_reg1_is_loreg);
+ *inst++ = REX_W;
+ *inst++ = MOV_rm_i32;
+ *inst++ = MOD_REG | reg_lmap[SLJIT_R0];
+ sljit_unaligned_store_s32(inst, local_size);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
+ }
+#endif
+
+ SLJIT_ASSERT(local_size > 0);
+ if (local_size <= 127) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+ *inst++ = REX_W;
+ *inst++ = GROUP_BINARY_83;
+ *inst++ = MOD_REG | SUB | 4;
+ *inst++ = local_size;
+ }
+ else {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
+ FAIL_IF(!inst);
+ INC_SIZE(7);
+ *inst++ = REX_W;
+ *inst++ = GROUP_BINARY_81;
+ *inst++ = MOD_REG | SUB | 4;
+ sljit_unaligned_store_s32(inst, local_size);
+ inst += sizeof(sljit_s32);
+ }
+
+#ifdef _WIN64
+ /* Save xmm6 register: movaps [rsp + 0x20], xmm6 */
+ if (fscratches >= 6 || fsaveds >= 1) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!inst);
+ INC_SIZE(5);
+ *inst++ = GROUP_0F;
+ sljit_unaligned_store_s32(inst, 0x20247429);
+ }
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 saved_register_size;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+
+ /* Including the return address saved by the call instruction. */
+ saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
+ compiler->local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 i, tmp, size;
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ compiler->flags_saved = 0;
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+#ifdef _WIN64
+ /* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */
+ if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!inst);
+ INC_SIZE(5);
+ *inst++ = GROUP_0F;
+ sljit_unaligned_store_s32(inst, 0x20247428);
+ }
+#endif
+
+ SLJIT_ASSERT(compiler->local_size > 0);
+ if (compiler->local_size <= 127) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+ *inst++ = REX_W;
+ *inst++ = GROUP_BINARY_83;
+ *inst++ = MOD_REG | ADD | 4;
+ *inst = compiler->local_size;
+ }
+ else {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
+ FAIL_IF(!inst);
+ INC_SIZE(7);
+ *inst++ = REX_W;
+ *inst++ = GROUP_BINARY_81;
+ *inst++ = MOD_REG | ADD | 4;
+ sljit_unaligned_store_s32(inst, compiler->local_size);
+ }
+
+ tmp = compiler->scratches;
+ for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
+ size = reg_map[i] >= 8 ? 2 : 1;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+ if (reg_map[i] >= 8)
+ *inst++ = REX_B;
+ POP_REG(reg_lmap[i]);
+ }
+
+ tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
+ for (i = tmp; i <= SLJIT_S0; i++) {
+ size = reg_map[i] >= 8 ? 2 : 1;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+ if (reg_map[i] >= 8)
+ *inst++ = REX_B;
+ POP_REG(reg_lmap[i]);
+ }
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ RET();
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+static sljit_s32 emit_do_imm32(struct sljit_compiler *compiler, sljit_u8 rex, sljit_u8 opcode, sljit_sw imm)
+{
+ sljit_u8 *inst;
+ sljit_s32 length = 1 + (rex ? 1 : 0) + sizeof(sljit_s32);
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + length);
+ FAIL_IF(!inst);
+ INC_SIZE(length);
+ if (rex)
+ *inst++ = rex;
+ *inst++ = opcode;
+ sljit_unaligned_store_s32(inst, imm);
+ return SLJIT_SUCCESS;
+}
+
+static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size,
+ /* The register or immediate operand. */
+ sljit_s32 a, sljit_sw imma,
+ /* The general operand (not immediate). */
+ sljit_s32 b, sljit_sw immb)
+{
+ sljit_u8 *inst;
+ sljit_u8 *buf_ptr;
+ sljit_u8 rex = 0;
+ sljit_s32 flags = size & ~0xf;
+ sljit_s32 inst_size;
+
+ /* The immediate operand must be 32 bit. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
+ /* Both cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
+ /* Size flags not allowed for typed instructions. */
+ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
+ /* Both size flags cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
+ /* SSE2 and immediate is not possible. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
+ SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
+ && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
+ && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
+
+ size &= 0xf;
+ inst_size = size;
+
+ if (!compiler->mode32 && !(flags & EX86_NO_REXW))
+ rex |= REX_W;
+ else if (flags & EX86_REX)
+ rex |= REX;
+
+ if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
+ inst_size++;
+ if (flags & EX86_PREF_66)
+ inst_size++;
+
+ /* Calculate size of b. */
+ inst_size += 1; /* mod r/m byte. */
+ if (b & SLJIT_MEM) {
+ if (!(b & OFFS_REG_MASK)) {
+ if (NOT_HALFWORD(immb)) {
+ if (emit_load_imm64(compiler, TMP_REG3, immb))
+ return NULL;
+ immb = 0;
+ if (b & REG_MASK)
+ b |= TO_OFFS_REG(TMP_REG3);
+ else
+ b |= TMP_REG3;
+ }
+ else if (reg_lmap[b & REG_MASK] == 4)
+ b |= TO_OFFS_REG(SLJIT_SP);
+ }
+
+ if ((b & REG_MASK) == SLJIT_UNUSED)
+ inst_size += 1 + sizeof(sljit_s32); /* SIB byte required to avoid RIP based addressing. */
+ else {
+ if (reg_map[b & REG_MASK] >= 8)
+ rex |= REX_B;
+
+ if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) {
+ /* Immediate operand. */
+ if (immb <= 127 && immb >= -128)
+ inst_size += sizeof(sljit_s8);
+ else
+ inst_size += sizeof(sljit_s32);
+ }
+ else if (reg_lmap[b & REG_MASK] == 5)
+ inst_size += sizeof(sljit_s8);
+
+ if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) {
+ inst_size += 1; /* SIB byte. */
+ if (reg_map[OFFS_REG(b)] >= 8)
+ rex |= REX_X;
+ }
+ }
+ }
+ else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8)
+ rex |= REX_B;
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BIN_INS) {
+ if (imma <= 127 && imma >= -128) {
+ inst_size += 1;
+ flags |= EX86_BYTE_ARG;
+ } else
+ inst_size += 4;
+ }
+ else if (flags & EX86_SHIFT_INS) {
+ imma &= compiler->mode32 ? 0x1f : 0x3f;
+ if (imma != 1) {
+ inst_size ++;
+ flags |= EX86_BYTE_ARG;
+ }
+ } else if (flags & EX86_BYTE_ARG)
+ inst_size++;
+ else if (flags & EX86_HALF_ARG)
+ inst_size += sizeof(short);
+ else
+ inst_size += sizeof(sljit_s32);
+ }
+ else {
+ SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
+ /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
+ if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8)
+ rex |= REX_R;
+ }
+
+ if (rex)
+ inst_size++;
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);
+ PTR_FAIL_IF(!inst);
+
+ /* Encoding the byte. */
+ INC_SIZE(inst_size);
+ if (flags & EX86_PREF_F2)
+ *inst++ = 0xf2;
+ if (flags & EX86_PREF_F3)
+ *inst++ = 0xf3;
+ if (flags & EX86_PREF_66)
+ *inst++ = 0x66;
+ if (rex)
+ *inst++ = rex;
+ buf_ptr = inst + size;
+
+ /* Encode mod/rm byte. */
+ if (!(flags & EX86_SHIFT_INS)) {
+ if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
+ *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
+
+ if ((a & SLJIT_IMM) || (a == 0))
+ *buf_ptr = 0;
+ else if (!(flags & EX86_SSE2_OP1))
+ *buf_ptr = reg_lmap[a] << 3;
+ else
+ *buf_ptr = a << 3;
+ }
+ else {
+ if (a & SLJIT_IMM) {
+ if (imma == 1)
+ *inst = GROUP_SHIFT_1;
+ else
+ *inst = GROUP_SHIFT_N;
+ } else
+ *inst = GROUP_SHIFT_CL;
+ *buf_ptr = 0;
+ }
+
+ if (!(b & SLJIT_MEM))
+ *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b);
+ else if ((b & REG_MASK) != SLJIT_UNUSED) {
+ if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
+ if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr |= 0x40;
+ else
+ *buf_ptr |= 0x80;
+ }
+
+ if ((b & OFFS_REG_MASK) == SLJIT_UNUSED)
+ *buf_ptr++ |= reg_lmap[b & REG_MASK];
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3);
+ }
+
+ if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr++ = immb; /* 8 bit displacement. */
+ else {
+ sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_s32);
+ }
+ }
+ }
+ else {
+ if (reg_lmap[b & REG_MASK] == 5)
+ *buf_ptr |= 0x40;
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6);
+ if (reg_lmap[b & REG_MASK] == 5)
+ *buf_ptr++ = 0;
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = 0x25;
+ sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_s32);
+ }
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BYTE_ARG)
+ *buf_ptr = imma;
+ else if (flags & EX86_HALF_ARG)
+ sljit_unaligned_store_s16(buf_ptr, imma);
+ else if (!(flags & EX86_SHIFT_INS))
+ sljit_unaligned_store_s32(buf_ptr, imma);
+ }
+
+ return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
+}
+
+/* --------------------------------------------------------------------- */
+/* Call / return instructions */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ sljit_u8 *inst;
+
+#ifndef _WIN64
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
+ FAIL_IF(!inst);
+ INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
+ if (type >= SLJIT_CALL3) {
+ *inst++ = REX_W;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_R2];
+ }
+ *inst++ = REX_W;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_R0];
+#else
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
+ FAIL_IF(!inst);
+ INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
+ if (type >= SLJIT_CALL3) {
+ *inst++ = REX_W | REX_R;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_R2];
+ }
+ *inst++ = REX_W;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_R0];
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ dst = TMP_REG1;
+
+ if (FAST_IS_REG(dst)) {
+ if (reg_map[dst] < 8) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ POP_REG(reg_lmap[dst]);
+ return SLJIT_SUCCESS;
+ }
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(2);
+ *inst++ = REX_B;
+ POP_REG(reg_lmap[dst]);
+ return SLJIT_SUCCESS;
+ }
+
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst++ = POP_rm;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));
+ src = TMP_REG1;
+ }
+
+ if (FAST_IS_REG(src)) {
+ if (reg_map[src] < 8) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
+ FAIL_IF(!inst);
+
+ INC_SIZE(1 + 1);
+ PUSH_REG(reg_lmap[src]);
+ }
+ else {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1);
+ FAIL_IF(!inst);
+
+ INC_SIZE(2 + 1);
+ *inst++ = REX_B;
+ PUSH_REG(reg_lmap[src]);
+ }
+ }
+ else if (src & SLJIT_MEM) {
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+ inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_FF;
+ *inst |= PUSH_rm;
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ }
+ else {
+ SLJIT_ASSERT(IS_HALFWORD(srcw));
+ /* SLJIT_IMM. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
+ FAIL_IF(!inst);
+
+ INC_SIZE(5 + 1);
+ *inst++ = PUSH_i32;
+ sljit_unaligned_store_s32(inst, srcw);
+ inst += sizeof(sljit_s32);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Extend input */
+/* --------------------------------------------------------------------- */
+
+static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+ sljit_s32 dst_r;
+
+ compiler->mode32 = 0;
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (FAST_IS_REG(dst)) {
+ if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_i32;
+ return SLJIT_SUCCESS;
+ }
+ return emit_load_imm64(compiler, dst, srcw);
+ }
+ compiler->mode32 = 1;
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_i32;
+ compiler->mode32 = 0;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if ((dst & SLJIT_MEM) && FAST_IS_REG(src))
+ dst_r = src;
+ else {
+ if (sign) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = MOVSXD_r_rm;
+ } else {
+ compiler->mode32 = 1;
+ FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
+ compiler->mode32 = 0;
+ }
+ }
+
+ if (dst & SLJIT_MEM) {
+ compiler->mode32 = 1;
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_r;
+ compiler->mode32 = 0;
+ }
+
+ return SLJIT_SUCCESS;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
new file mode 100644
index 0000000000..12a0e272af
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
@@ -0,0 +1,3030 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "x86" SLJIT_CPUINFO;
+}
+
+/*
+ 32b register indexes:
+ 0 - EAX
+ 1 - ECX
+ 2 - EDX
+ 3 - EBX
+ 4 - none
+ 5 - EBP
+ 6 - ESI
+ 7 - EDI
+*/
+
+/*
+ 64b register indexes:
+ 0 - RAX
+ 1 - RCX
+ 2 - RDX
+ 3 - RBX
+ 4 - none
+ 5 - RBP
+ 6 - RSI
+ 7 - RDI
+ 8 - R8 - From now on REX prefix is required
+ 9 - R9
+ 10 - R10
+ 11 - R11
+ 12 - R12
+ 13 - R13
+ 14 - R14
+ 15 - R15
+*/
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {
+ 0, 0, 2, 1, 0, 0, 0, 0, 7, 6, 3, 4, 5
+};
+
+#define CHECK_EXTRA_REGS(p, w, do) \
+ if (p >= SLJIT_R3 && p <= SLJIT_R6) { \
+ w = SLJIT_LOCALS_OFFSET + ((p) - (SLJIT_R3 + 4)) * sizeof(sljit_sw); \
+ p = SLJIT_MEM1(SLJIT_SP); \
+ do; \
+ }
+
+#else /* SLJIT_CONFIG_X86_32 */
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
+
+/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
+ Note: avoid to use r12 and r13 for memory addessing
+ therefore r12 is better for SAVED_EREG than SAVED_REG. */
+#ifndef _WIN64
+/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
+ 0, 0, 6, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 7, 9
+};
+/* low-map. reg_map & 0x7. */
+static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = {
+ 0, 0, 6, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 7, 1
+};
+#else
+/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
+ 0, 0, 2, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 10, 8, 9
+};
+/* low-map. reg_map & 0x7. */
+static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = {
+ 0, 0, 2, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 2, 0, 1
+};
+#endif
+
+#define REX_W 0x48
+#define REX_R 0x44
+#define REX_X 0x42
+#define REX_B 0x41
+#define REX 0x40
+
+#ifndef _WIN64
+#define HALFWORD_MAX 0x7fffffffl
+#define HALFWORD_MIN -0x80000000l
+#else
+#define HALFWORD_MAX 0x7fffffffll
+#define HALFWORD_MIN -0x80000000ll
+#endif
+
+#define IS_HALFWORD(x) ((x) <= HALFWORD_MAX && (x) >= HALFWORD_MIN)
+#define NOT_HALFWORD(x) ((x) > HALFWORD_MAX || (x) < HALFWORD_MIN)
+
+#define CHECK_EXTRA_REGS(p, w, do)
+
+#endif /* SLJIT_CONFIG_X86_32 */
+
+#define TMP_FREG (0)
+
+/* Size flags for emit_x86_instruction: */
+#define EX86_BIN_INS 0x0010
+#define EX86_SHIFT_INS 0x0020
+#define EX86_REX 0x0040
+#define EX86_NO_REXW 0x0080
+#define EX86_BYTE_ARG 0x0100
+#define EX86_HALF_ARG 0x0200
+#define EX86_PREF_66 0x0400
+#define EX86_PREF_F2 0x0800
+#define EX86_PREF_F3 0x1000
+#define EX86_SSE2_OP1 0x2000
+#define EX86_SSE2_OP2 0x4000
+#define EX86_SSE2 (EX86_SSE2_OP1 | EX86_SSE2_OP2)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+#define ADD (/* BINARY */ 0 << 3)
+#define ADD_EAX_i32 0x05
+#define ADD_r_rm 0x03
+#define ADD_rm_r 0x01
+#define ADDSD_x_xm 0x58
+#define ADC (/* BINARY */ 2 << 3)
+#define ADC_EAX_i32 0x15
+#define ADC_r_rm 0x13
+#define ADC_rm_r 0x11
+#define AND (/* BINARY */ 4 << 3)
+#define AND_EAX_i32 0x25
+#define AND_r_rm 0x23
+#define AND_rm_r 0x21
+#define ANDPD_x_xm 0x54
+#define BSR_r_rm (/* GROUP_0F */ 0xbd)
+#define CALL_i32 0xe8
+#define CALL_rm (/* GROUP_FF */ 2 << 3)
+#define CDQ 0x99
+#define CMOVNE_r_rm (/* GROUP_0F */ 0x45)
+#define CMP (/* BINARY */ 7 << 3)
+#define CMP_EAX_i32 0x3d
+#define CMP_r_rm 0x3b
+#define CMP_rm_r 0x39
+#define CVTPD2PS_x_xm 0x5a
+#define CVTSI2SD_x_rm 0x2a
+#define CVTTSD2SI_r_xm 0x2c
+#define DIV (/* GROUP_F7 */ 6 << 3)
+#define DIVSD_x_xm 0x5e
+#define INT3 0xcc
+#define IDIV (/* GROUP_F7 */ 7 << 3)
+#define IMUL (/* GROUP_F7 */ 5 << 3)
+#define IMUL_r_rm (/* GROUP_0F */ 0xaf)
+#define IMUL_r_rm_i8 0x6b
+#define IMUL_r_rm_i32 0x69
+#define JE_i8 0x74
+#define JNE_i8 0x75
+#define JMP_i8 0xeb
+#define JMP_i32 0xe9
+#define JMP_rm (/* GROUP_FF */ 4 << 3)
+#define LEA_r_m 0x8d
+#define MOV_r_rm 0x8b
+#define MOV_r_i32 0xb8
+#define MOV_rm_r 0x89
+#define MOV_rm_i32 0xc7
+#define MOV_rm8_i8 0xc6
+#define MOV_rm8_r8 0x88
+#define MOVSD_x_xm 0x10
+#define MOVSD_xm_x 0x11
+#define MOVSXD_r_rm 0x63
+#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe)
+#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf)
+#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6)
+#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7)
+#define MUL (/* GROUP_F7 */ 4 << 3)
+#define MULSD_x_xm 0x59
+#define NEG_rm (/* GROUP_F7 */ 3 << 3)
+#define NOP 0x90
+#define NOT_rm (/* GROUP_F7 */ 2 << 3)
+#define OR (/* BINARY */ 1 << 3)
+#define OR_r_rm 0x0b
+#define OR_EAX_i32 0x0d
+#define OR_rm_r 0x09
+#define OR_rm8_r8 0x08
+#define POP_r 0x58
+#define POP_rm 0x8f
+#define POPF 0x9d
+#define PUSH_i32 0x68
+#define PUSH_r 0x50
+#define PUSH_rm (/* GROUP_FF */ 6 << 3)
+#define PUSHF 0x9c
+#define RET_near 0xc3
+#define RET_i16 0xc2
+#define SBB (/* BINARY */ 3 << 3)
+#define SBB_EAX_i32 0x1d
+#define SBB_r_rm 0x1b
+#define SBB_rm_r 0x19
+#define SAR (/* SHIFT */ 7 << 3)
+#define SHL (/* SHIFT */ 4 << 3)
+#define SHR (/* SHIFT */ 5 << 3)
+#define SUB (/* BINARY */ 5 << 3)
+#define SUB_EAX_i32 0x2d
+#define SUB_r_rm 0x2b
+#define SUB_rm_r 0x29
+#define SUBSD_x_xm 0x5c
+#define TEST_EAX_i32 0xa9
+#define TEST_rm_r 0x85
+#define UCOMISD_x_xm 0x2e
+#define UNPCKLPD_x_xm 0x14
+#define XCHG_EAX_r 0x90
+#define XCHG_r_rm 0x87
+#define XOR (/* BINARY */ 6 << 3)
+#define XOR_EAX_i32 0x35
+#define XOR_r_rm 0x33
+#define XOR_rm_r 0x31
+#define XORPD_x_xm 0x57
+
+#define GROUP_0F 0x0f
+#define GROUP_F7 0xf7
+#define GROUP_FF 0xff
+#define GROUP_BINARY_81 0x81
+#define GROUP_BINARY_83 0x83
+#define GROUP_SHIFT_1 0xd1
+#define GROUP_SHIFT_N 0xc1
+#define GROUP_SHIFT_CL 0xd3
+
+#define MOD_REG 0xc0
+#define MOD_DISP8 0x40
+
+#define INC_SIZE(s) (*inst++ = (s), compiler->size += (s))
+
+#define PUSH_REG(r) (*inst++ = (PUSH_r + (r)))
+#define POP_REG(r) (*inst++ = (POP_r + (r)))
+#define RET() (*inst++ = (RET_near))
+#define RET_I16(n) (*inst++ = (RET_i16), *inst++ = n, *inst++ = 0)
+/* r32, r/m32 */
+#define MOV_RM(mod, reg, rm) (*inst++ = (MOV_r_rm), *inst++ = (mod) << 6 | (reg) << 3 | (rm))
+
+/* Multithreading does not affect these static variables, since they store
+ built-in CPU features. Therefore they can be overwritten by different threads
+ if they detect the CPU features in the same time. */
+#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
+static sljit_s32 cpu_has_sse2 = -1;
+#endif
+static sljit_s32 cpu_has_cmov = -1;
+
+#ifdef _WIN32_WCE
+#include <cmnintrin.h>
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
+#include <intrin.h>
+#endif
+
+/******************************************************/
+/* Unaligned-store functions */
+/******************************************************/
+
+static SLJIT_INLINE void sljit_unaligned_store_s16(void *addr, sljit_s16 value)
+{
+ SLJIT_MEMCPY(addr, &value, sizeof(value));
+}
+
+static SLJIT_INLINE void sljit_unaligned_store_s32(void *addr, sljit_s32 value)
+{
+ SLJIT_MEMCPY(addr, &value, sizeof(value));
+}
+
+static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value)
+{
+ SLJIT_MEMCPY(addr, &value, sizeof(value));
+}
+
+/******************************************************/
+/* Utility functions */
+/******************************************************/
+
+static void get_cpu_features(void)
+{
+ sljit_u32 features;
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+ int CPUInfo[4];
+ __cpuid(CPUInfo, 1);
+ features = (sljit_u32)CPUInfo[3];
+
+#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
+
+ /* AT&T syntax. */
+ __asm__ (
+ "movl $0x1, %%eax\n"
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ /* On x86-32, there is no red zone, so this
+ should work (no need for a local variable). */
+ "push %%ebx\n"
+#endif
+ "cpuid\n"
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ "pop %%ebx\n"
+#endif
+ "movl %%edx, %0\n"
+ : "=g" (features)
+ :
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ : "%eax", "%ecx", "%edx"
+#else
+ : "%rax", "%rbx", "%rcx", "%rdx"
+#endif
+ );
+
+#else /* _MSC_VER && _MSC_VER >= 1400 */
+
+ /* Intel syntax. */
+ __asm {
+ mov eax, 1
+ cpuid
+ mov features, edx
+ }
+
+#endif /* _MSC_VER && _MSC_VER >= 1400 */
+
+#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
+ cpu_has_sse2 = (features >> 26) & 0x1;
+#endif
+ cpu_has_cmov = (features >> 15) & 0x1;
+}
+
+static sljit_u8 get_jump_code(sljit_s32 type)
+{
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_EQUAL_F64:
+ return 0x84 /* je */;
+
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_NOT_EQUAL_F64:
+ return 0x85 /* jne */;
+
+ case SLJIT_LESS:
+ case SLJIT_LESS_F64:
+ return 0x82 /* jc */;
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ return 0x83 /* jae */;
+
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_F64:
+ return 0x87 /* jnbe */;
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return 0x86 /* jbe */;
+
+ case SLJIT_SIG_LESS:
+ return 0x8c /* jl */;
+
+ case SLJIT_SIG_GREATER_EQUAL:
+ return 0x8d /* jnl */;
+
+ case SLJIT_SIG_GREATER:
+ return 0x8f /* jnle */;
+
+ case SLJIT_SIG_LESS_EQUAL:
+ return 0x8e /* jle */;
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_MUL_OVERFLOW:
+ return 0x80 /* jo */;
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ return 0x81 /* jno */;
+
+ case SLJIT_UNORDERED_F64:
+ return 0x8a /* jp */;
+
+ case SLJIT_ORDERED_F64:
+ return 0x8b /* jpo */;
+ }
+ return 0;
+}
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset);
+#else
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type);
+#endif
+
+static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset)
+{
+ sljit_s32 short_jump;
+ sljit_uw label_addr;
+
+ if (jump->flags & JUMP_LABEL)
+ label_addr = (sljit_uw)(code + jump->u.label->size);
+ else
+ label_addr = jump->u.target - executable_offset;
+
+ short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN)
+ return generate_far_jump_code(jump, code_ptr, type);
+#endif
+
+ if (type == SLJIT_JUMP) {
+ if (short_jump)
+ *code_ptr++ = JMP_i8;
+ else
+ *code_ptr++ = JMP_i32;
+ jump->addr++;
+ }
+ else if (type >= SLJIT_FAST_CALL) {
+ short_jump = 0;
+ *code_ptr++ = CALL_i32;
+ jump->addr++;
+ }
+ else if (short_jump) {
+ *code_ptr++ = get_jump_code(type) - 0x10;
+ jump->addr++;
+ }
+ else {
+ *code_ptr++ = GROUP_0F;
+ *code_ptr++ = get_jump_code(type);
+ jump->addr += 2;
+ }
+
+ if (short_jump) {
+ jump->flags |= PATCH_MB;
+ code_ptr += sizeof(sljit_s8);
+ } else {
+ jump->flags |= PATCH_MW;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code_ptr += sizeof(sljit_sw);
+#else
+ code_ptr += sizeof(sljit_s32);
+#endif
+ }
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_u8 *code;
+ sljit_u8 *code_ptr;
+ sljit_u8 *buf_ptr;
+ sljit_u8 *buf_end;
+ sljit_u8 len;
+ sljit_sw executable_offset;
+ sljit_sw jump_addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ /* Second code generation pass. */
+ code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size);
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ do {
+ buf_ptr = buf->memory;
+ buf_end = buf_ptr + buf->used_size;
+ do {
+ len = *buf_ptr++;
+ if (len > 0) {
+ /* The code is already generated. */
+ SLJIT_MEMCPY(code_ptr, buf_ptr, len);
+ code_ptr += len;
+ buf_ptr += len;
+ }
+ else {
+ if (*buf_ptr >= 2) {
+ jump->addr = (sljit_uw)code_ptr;
+ if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
+ code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset);
+ else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2, executable_offset);
+#else
+ code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2);
+#endif
+ }
+ jump = jump->next;
+ }
+ else if (*buf_ptr == 0) {
+ label->addr = ((sljit_uw)code_ptr) + executable_offset;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ else { /* *buf_ptr is 1 */
+ const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
+ const_ = const_->next;
+ }
+ buf_ptr++;
+ }
+ } while (buf_ptr < buf_end);
+ SLJIT_ASSERT(buf_ptr == buf_end);
+ buf = buf->next;
+ } while (buf);
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+
+ jump = compiler->jumps;
+ while (jump) {
+ jump_addr = jump->addr + executable_offset;
+
+ if (jump->flags & PATCH_MB) {
+ SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8))) <= 127);
+ *(sljit_u8*)jump->addr = (sljit_u8)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8)));
+ } else if (jump->flags & PATCH_MW) {
+ if (jump->flags & JUMP_LABEL) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_sw))));
+#else
+ SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s32))) <= HALFWORD_MAX);
+ sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.label->addr - (jump_addr + sizeof(sljit_s32))));
+#endif
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.target - (jump_addr + sizeof(sljit_sw))));
+#else
+ SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump_addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump_addr + sizeof(sljit_s32))) <= HALFWORD_MAX);
+ sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.target - (jump_addr + sizeof(sljit_s32))));
+#endif
+ }
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ else if (jump->flags & PATCH_MD)
+ sljit_unaligned_store_sw((void*)jump->addr, jump->u.label->addr);
+#endif
+
+ jump = jump->next;
+ }
+
+ /* Some space may be wasted because of short jumps. */
+ SLJIT_ASSERT(code_ptr <= code + compiler->size);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = code_ptr - code;
+ return (void*)(code + executable_offset);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
+ sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
+ sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+static sljit_s32 emit_mov(struct sljit_compiler *compiler,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw);
+
+static SLJIT_INLINE sljit_s32 emit_save_flags(struct sljit_compiler *compiler)
+{
+ sljit_u8 *inst;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!inst);
+ INC_SIZE(5);
+#else
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 6);
+ FAIL_IF(!inst);
+ INC_SIZE(6);
+ *inst++ = REX_W;
+#endif
+ *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */
+ *inst++ = 0x64;
+ *inst++ = 0x24;
+ *inst++ = (sljit_u8)sizeof(sljit_sw);
+ *inst++ = PUSHF;
+ compiler->flags_saved = 1;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_restore_flags(struct sljit_compiler *compiler, sljit_s32 keep_flags)
+{
+ sljit_u8 *inst;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!inst);
+ INC_SIZE(5);
+ *inst++ = POPF;
+#else
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 6);
+ FAIL_IF(!inst);
+ INC_SIZE(6);
+ *inst++ = POPF;
+ *inst++ = REX_W;
+#endif
+ *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */
+ *inst++ = 0x64;
+ *inst++ = 0x24;
+ *inst++ = (sljit_u8)(-(sljit_s8)sizeof(sljit_sw));
+ compiler->flags_saved = keep_flags;
+ return SLJIT_SUCCESS;
+}
+
+#ifdef _WIN32
+#include <malloc.h>
+
+static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size)
+{
+ /* Workaround for calling the internal _chkstk() function on Windows.
+ This function touches all 4k pages belongs to the requested stack space,
+ which size is passed in local_size. This is necessary on Windows where
+ the stack can only grow in 4k steps. However, this function just burn
+ CPU cycles if the stack is large enough. However, you don't know it in
+ advance, so it must always be called. I think this is a bad design in
+ general even if it has some reasons. */
+ *(volatile sljit_s32*)alloca(local_size) = 0;
+}
+
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#include "sljitNativeX86_32.c"
+#else
+#include "sljitNativeX86_64.c"
+#endif
+
+static sljit_s32 emit_mov(struct sljit_compiler *compiler,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+
+ if (dst == SLJIT_UNUSED) {
+ /* No destination, doesn't need to setup flags. */
+ if (src & SLJIT_MEM) {
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst = MOV_r_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+ if (FAST_IS_REG(src)) {
+ inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_r;
+ return SLJIT_SUCCESS;
+ }
+ if (src & SLJIT_IMM) {
+ if (FAST_IS_REG(dst)) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);
+#else
+ if (!compiler->mode32) {
+ if (NOT_HALFWORD(srcw))
+ return emit_load_imm64(compiler, dst, srcw);
+ }
+ else
+ return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, MOV_r_i32 + reg_lmap[dst], srcw);
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw));
+ inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_r;
+ return SLJIT_SUCCESS;
+ }
+#endif
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_i32;
+ return SLJIT_SUCCESS;
+ }
+ if (FAST_IS_REG(dst)) {
+ inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst = MOV_r_rm;
+ return SLJIT_SUCCESS;
+ }
+
+ /* Memory to memory move. Requires two instruction. */
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst = MOV_r_rm;
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_r;
+ return SLJIT_SUCCESS;
+}
+
+#define EMIT_MOV(compiler, dst, dstw, src, srcw) \
+ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ sljit_u8 *inst;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ sljit_s32 size;
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_BREAKPOINT:
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ *inst = INT3;
+ break;
+ case SLJIT_NOP:
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ *inst = NOP;
+ break;
+ case SLJIT_LMUL_UW:
+ case SLJIT_LMUL_SW:
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIVMOD_SW:
+ case SLJIT_DIV_UW:
+ case SLJIT_DIV_SW:
+ compiler->flags_saved = 0;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+#ifdef _WIN64
+ SLJIT_COMPILE_ASSERT(
+ reg_map[SLJIT_R0] == 0
+ && reg_map[SLJIT_R1] == 2
+ && reg_map[TMP_REG1] > 7,
+ invalid_register_assignment_for_div_mul);
+#else
+ SLJIT_COMPILE_ASSERT(
+ reg_map[SLJIT_R0] == 0
+ && reg_map[SLJIT_R1] < 7
+ && reg_map[TMP_REG1] == 2,
+ invalid_register_assignment_for_div_mul);
+#endif
+ compiler->mode32 = op & SLJIT_I32_OP;
+#endif
+ SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
+
+ op = GET_OPCODE(op);
+ if ((op | 0x2) == SLJIT_DIV_UW) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
+ inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0);
+#else
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);
+#endif
+ FAIL_IF(!inst);
+ *inst = XOR_r_rm;
+ }
+
+ if ((op | 0x2) == SLJIT_DIV_SW) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ *inst = CDQ;
+#else
+ if (compiler->mode32) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ *inst = CDQ;
+ } else {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(2);
+ *inst++ = REX_W;
+ *inst = CDQ;
+ }
+#endif
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(2);
+ *inst++ = GROUP_F7;
+ *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);
+#else
+#ifdef _WIN64
+ size = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2;
+#else
+ size = (!compiler->mode32) ? 3 : 2;
+#endif
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+#ifdef _WIN64
+ if (!compiler->mode32)
+ *inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0);
+ else if (op >= SLJIT_DIVMOD_UW)
+ *inst++ = REX_B;
+ *inst++ = GROUP_F7;
+ *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);
+#else
+ if (!compiler->mode32)
+ *inst++ = REX_W;
+ *inst++ = GROUP_F7;
+ *inst = MOD_REG | reg_map[SLJIT_R1];
+#endif
+#endif
+ switch (op) {
+ case SLJIT_LMUL_UW:
+ *inst |= MUL;
+ break;
+ case SLJIT_LMUL_SW:
+ *inst |= IMUL;
+ break;
+ case SLJIT_DIVMOD_UW:
+ case SLJIT_DIV_UW:
+ *inst |= DIV;
+ break;
+ case SLJIT_DIVMOD_SW:
+ case SLJIT_DIV_SW:
+ *inst |= IDIV;
+ break;
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
+ if (op <= SLJIT_DIVMOD_SW)
+ EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
+#else
+ if (op >= SLJIT_DIV_UW)
+ EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
+#endif
+ break;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+#define ENCODE_PREFIX(prefix) \
+ do { \
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \
+ FAIL_IF(!inst); \
+ INC_SIZE(1); \
+ *inst = (prefix); \
+ } while (0)
+
+static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+ sljit_s32 dst_r;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_s32 work_r;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (FAST_IS_REG(dst)) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);
+#else
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_i32;
+ return SLJIT_SUCCESS;
+#endif
+ }
+ inst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm8_i8;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (reg_map[src] >= 4) {
+ SLJIT_ASSERT(dst_r == TMP_REG1);
+ EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
+ } else
+ dst_r = src;
+#else
+ dst_r = src;
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else if (FAST_IS_REG(src) && reg_map[src] >= 4) {
+ /* src, dst are registers. */
+ SLJIT_ASSERT(SLOW_IS_REG(dst));
+ if (reg_map[dst] < 4) {
+ if (dst != src)
+ EMIT_MOV(compiler, dst, 0, src, 0);
+ inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8;
+ }
+ else {
+ if (dst != src)
+ EMIT_MOV(compiler, dst, 0, src, 0);
+ if (sign) {
+ /* shl reg, 24 */
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
+ FAIL_IF(!inst);
+ *inst |= SHL;
+ /* sar reg, 24 */
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
+ FAIL_IF(!inst);
+ *inst |= SAR;
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0);
+ FAIL_IF(!inst);
+ *(inst + 1) |= AND;
+ }
+ }
+ return SLJIT_SUCCESS;
+ }
+#endif
+ else {
+ /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8;
+ }
+
+ if (dst & SLJIT_MEM) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst_r == TMP_REG1) {
+ /* Find a non-used register, whose reg_map[src] < 4. */
+ if ((dst & REG_MASK) == SLJIT_R0) {
+ if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1))
+ work_r = SLJIT_R2;
+ else
+ work_r = SLJIT_R1;
+ }
+ else {
+ if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0))
+ work_r = SLJIT_R0;
+ else if ((dst & REG_MASK) == SLJIT_R1)
+ work_r = SLJIT_R2;
+ else
+ work_r = SLJIT_R1;
+ }
+
+ if (work_r == SLJIT_R0) {
+ ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
+ FAIL_IF(!inst);
+ *inst = XCHG_r_rm;
+ }
+
+ inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm8_r8;
+
+ if (work_r == SLJIT_R0) {
+ ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
+ FAIL_IF(!inst);
+ *inst = XCHG_r_rm;
+ }
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm8_r8;
+ }
+#else
+ inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm8_r8;
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+ sljit_s32 dst_r;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (FAST_IS_REG(dst)) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);
+#else
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_i32;
+ return SLJIT_SUCCESS;
+#endif
+ }
+ inst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_i32;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if ((dst & SLJIT_MEM) && FAST_IS_REG(src))
+ dst_r = src;
+ else {
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16;
+ }
+
+ if (dst & SLJIT_MEM) {
+ inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = MOV_rm_r;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
+ inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= opcode;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == src && dstw == srcw) {
+ /* Same input and output */
+ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= opcode;
+ return SLJIT_SUCCESS;
+ }
+ if (FAST_IS_REG(dst)) {
+ EMIT_MOV(compiler, dst, 0, src, srcw);
+ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= opcode;
+ return SLJIT_SUCCESS;
+ }
+ EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
+ inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= opcode;
+ EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
+ inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= NOT_rm;
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst = OR_r_rm;
+ return SLJIT_SUCCESS;
+ }
+ if (FAST_IS_REG(dst)) {
+ EMIT_MOV(compiler, dst, 0, src, srcw);
+ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= NOT_rm;
+ inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
+ FAIL_IF(!inst);
+ *inst = OR_r_rm;
+ return SLJIT_SUCCESS;
+ }
+ EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
+ inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= NOT_rm;
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst = OR_r_rm;
+ EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_clz(struct sljit_compiler *compiler, sljit_s32 op_flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+ sljit_s32 dst_r;
+
+ SLJIT_UNUSED_ARG(op_flags);
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ /* Just set the zero flag. */
+ EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
+ inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_F7;
+ *inst |= NOT_rm;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REG1, 0);
+#else
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, TMP_REG1, 0);
+#endif
+ FAIL_IF(!inst);
+ *inst |= SHR;
+ return SLJIT_SUCCESS;
+ }
+
+ if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ inst = emit_x86_instruction(compiler, 2, TMP_REG1, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = BSR_r_rm;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (FAST_IS_REG(dst))
+ dst_r = dst;
+ else {
+ /* Find an unused temporary register. */
+ if ((dst & REG_MASK) != SLJIT_R0 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0))
+ dst_r = SLJIT_R0;
+ else if ((dst & REG_MASK) != SLJIT_R1 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R1))
+ dst_r = SLJIT_R1;
+ else
+ dst_r = SLJIT_R2;
+ EMIT_MOV(compiler, dst, dstw, dst_r, 0);
+ }
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
+#else
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ compiler->mode32 = 0;
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 64 + 63 : 32 + 31);
+ compiler->mode32 = op_flags & SLJIT_I32_OP;
+#endif
+
+ if (cpu_has_cmov == -1)
+ get_cpu_features();
+
+ if (cpu_has_cmov) {
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = CMOVNE_r_rm;
+ } else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+
+ *inst++ = JE_i8;
+ *inst++ = 2;
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REG1];
+#else
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!inst);
+ INC_SIZE(5);
+
+ *inst++ = JE_i8;
+ *inst++ = 3;
+ *inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REG1] >= 8 ? REX_B : 0);
+ *inst++ = MOV_r_rm;
+ *inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REG1];
+#endif
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
+#else
+ inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, dst_r, 0);
+#endif
+ FAIL_IF(!inst);
+ *(inst + 1) |= XOR;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst & SLJIT_MEM) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = XCHG_r_rm;
+ }
+#else
+ if (dst & SLJIT_MEM)
+ EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+ sljit_s32 update = 0;
+ sljit_s32 op_flags = GET_ALL_FLAGS(op);
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_s32 dst_is_ereg = 0;
+ sljit_s32 src_is_ereg = 0;
+#else
+# define src_is_ereg 0
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
+ CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = op_flags & SLJIT_I32_OP;
+#endif
+
+ op = GET_OPCODE(op);
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ if (op_flags & SLJIT_I32_OP) {
+ if (FAST_IS_REG(src) && src == dst) {
+ if (!TYPE_CAST_NEEDED(op))
+ return SLJIT_SUCCESS;
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM))
+ op = SLJIT_MOV_U32;
+ if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM))
+ op = SLJIT_MOVU_U32;
+ if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM))
+ op = SLJIT_MOV_S32;
+ if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM))
+ op = SLJIT_MOVU_S32;
+#endif
+ }
+
+ SLJIT_COMPILE_ASSERT(SLJIT_MOV + 8 == SLJIT_MOVU, movu_offset);
+ if (op >= SLJIT_MOVU) {
+ update = 1;
+ op -= 8;
+ }
+
+ if (src & SLJIT_IMM) {
+ switch (op) {
+ case SLJIT_MOV_U8:
+ srcw = (sljit_u8)srcw;
+ break;
+ case SLJIT_MOV_S8:
+ srcw = (sljit_s8)srcw;
+ break;
+ case SLJIT_MOV_U16:
+ srcw = (sljit_u16)srcw;
+ break;
+ case SLJIT_MOV_S16:
+ srcw = (sljit_s16)srcw;
+ break;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ case SLJIT_MOV_U32:
+ srcw = (sljit_u32)srcw;
+ break;
+ case SLJIT_MOV_S32:
+ srcw = (sljit_s32)srcw;
+ break;
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg))
+ return emit_mov(compiler, dst, dstw, src, srcw);
+#endif
+ }
+
+ if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & REG_MASK) && (srcw != 0 || (src & OFFS_REG_MASK) != 0)) {
+ inst = emit_x86_instruction(compiler, 1, src & REG_MASK, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst = LEA_r_m;
+ src &= SLJIT_MEM | 0xf;
+ srcw = 0;
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) {
+ SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP));
+ dst = TMP_REG1;
+ }
+#endif
+
+ switch (op) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+#endif
+ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
+ break;
+ case SLJIT_MOV_U8:
+ FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw));
+ break;
+ case SLJIT_MOV_S8:
+ FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw));
+ break;
+ case SLJIT_MOV_U16:
+ FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw));
+ break;
+ case SLJIT_MOV_S16:
+ FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw));
+ break;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ case SLJIT_MOV_U32:
+ FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw));
+ break;
+ case SLJIT_MOV_S32:
+ FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw));
+ break;
+#endif
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1)
+ return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0);
+#endif
+
+ if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & REG_MASK) && (dstw != 0 || (dst & OFFS_REG_MASK) != 0)) {
+ inst = emit_x86_instruction(compiler, 1, dst & REG_MASK, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = LEA_r_m;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (SLJIT_UNLIKELY(GET_FLAGS(op_flags)))
+ compiler->flags_saved = 0;
+
+ switch (op) {
+ case SLJIT_NOT:
+ if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_E))
+ return emit_not_with_flags(compiler, dst, dstw, src, srcw);
+ return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw);
+
+ case SLJIT_NEG:
+ if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_unary(compiler, NEG_rm, dst, dstw, src, srcw);
+
+ case SLJIT_CLZ:
+ if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_clz(compiler, op_flags, dst, dstw, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+# undef src_is_ereg
+#endif
+}
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \
+ if (IS_HALFWORD(immw) || compiler->mode32) { \
+ inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
+ FAIL_IF(!inst); \
+ *(inst + 1) |= (op_imm); \
+ } \
+ else { \
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
+ inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
+ FAIL_IF(!inst); \
+ *inst = (op_mr); \
+ }
+
+#define BINARY_EAX_IMM(op_eax_imm, immw) \
+ FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (op_eax_imm), immw))
+
+#else
+
+#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \
+ inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
+ FAIL_IF(!inst); \
+ *(inst + 1) |= (op_imm);
+
+#define BINARY_EAX_IMM(op_eax_imm, immw) \
+ FAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw))
+
+#endif
+
+static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
+ sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_u8* inst;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == src1 && dstw == src1w) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src2w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
+ }
+ }
+ else if (FAST_IS_REG(dst)) {
+ inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ else if (FAST_IS_REG(src2)) {
+ /* Special exception for sljit_emit_op_flags. */
+ inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* Only for cumulative operations. */
+ if (dst == src2 && dstw == src2w) {
+ if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+#else
+ if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src1w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
+ }
+ }
+ else if (FAST_IS_REG(dst)) {
+ inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ else if (FAST_IS_REG(src1)) {
+ inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* General version. */
+ if (FAST_IS_REG(dst)) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ }
+ else {
+ /* This version requires less memory writing. */
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
+ sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_u8* inst;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == src1 && dstw == src1w) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src2w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
+ }
+ }
+ else if (FAST_IS_REG(dst)) {
+ inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ else if (FAST_IS_REG(src2)) {
+ inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* General version. */
+ if (FAST_IS_REG(dst) && dst != src2) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ }
+ else {
+ /* This version requires less memory writing. */
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = op_rm;
+ }
+ EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_mul(struct sljit_compiler *compiler,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_u8* inst;
+ sljit_s32 dst_r;
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ /* Register destination. */
+ if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = IMUL_r_rm;
+ }
+ else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = IMUL_r_rm;
+ }
+ else if (src1 & SLJIT_IMM) {
+ if (src2 & SLJIT_IMM) {
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
+ src2 = dst_r;
+ src2w = 0;
+ }
+
+ if (src1w <= 127 && src1w >= -128) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = IMUL_r_rm_i8;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ *inst = (sljit_s8)src1w;
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = IMUL_r_rm_i32;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+ sljit_unaligned_store_sw(inst, src1w);
+ }
+#else
+ else if (IS_HALFWORD(src1w)) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = IMUL_r_rm_i32;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+ sljit_unaligned_store_s32(inst, (sljit_s32)src1w);
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
+ if (dst_r != src2)
+ EMIT_MOV(compiler, dst_r, 0, src2, src2w);
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = IMUL_r_rm;
+ }
+#endif
+ }
+ else if (src2 & SLJIT_IMM) {
+ /* Note: src1 is NOT immediate. */
+
+ if (src2w <= 127 && src2w >= -128) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = IMUL_r_rm_i8;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1);
+ *inst = (sljit_s8)src2w;
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = IMUL_r_rm_i32;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+ sljit_unaligned_store_sw(inst, src2w);
+ }
+#else
+ else if (IS_HALFWORD(src2w)) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = IMUL_r_rm_i32;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+ sljit_unaligned_store_s32(inst, (sljit_s32)src2w);
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src2w);
+ if (dst_r != src1)
+ EMIT_MOV(compiler, dst_r, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = IMUL_r_rm;
+ }
+#endif
+ }
+ else {
+ /* Neither argument is immediate. */
+ if (ADDRESSING_DEPENDS_ON(src2, dst_r))
+ dst_r = TMP_REG1;
+ EMIT_MOV(compiler, dst_r, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = IMUL_r_rm;
+ }
+
+ if (dst_r == TMP_REG1)
+ EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, sljit_s32 keep_flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_u8* inst;
+ sljit_s32 dst_r, done = 0;
+
+ /* These cases better be left to handled by normal way. */
+ if (!keep_flags) {
+ if (dst == src1 && dstw == src1w)
+ return SLJIT_ERR_UNSUPPORTED;
+ if (dst == src2 && dstw == src2w)
+ return SLJIT_ERR_UNSUPPORTED;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if (FAST_IS_REG(src1)) {
+ if (FAST_IS_REG(src2)) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
+ FAIL_IF(!inst);
+ *inst = LEA_r_m;
+ done = 1;
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w);
+#else
+ if (src2 & SLJIT_IMM) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
+#endif
+ FAIL_IF(!inst);
+ *inst = LEA_r_m;
+ done = 1;
+ }
+ }
+ else if (FAST_IS_REG(src2)) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w);
+#else
+ if (src1 & SLJIT_IMM) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
+#endif
+ FAIL_IF(!inst);
+ *inst = LEA_r_m;
+ done = 1;
+ }
+ }
+
+ if (done) {
+ if (dst_r == TMP_REG1)
+ return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
+ return SLJIT_SUCCESS;
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_u8* inst;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(CMP_EAX_i32, src2w);
+ return SLJIT_SUCCESS;
+ }
+
+ if (FAST_IS_REG(src1)) {
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0);
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = CMP_r_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) {
+ inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = CMP_rm_r;
+ return SLJIT_SUCCESS;
+ }
+
+ if (src2 & SLJIT_IMM) {
+ if (src1 & SLJIT_IMM) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ src1 = TMP_REG1;
+ src1w = 0;
+ }
+ BINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w);
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = CMP_r_rm;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_test_binary(struct sljit_compiler *compiler,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_u8* inst;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(TEST_EAX_i32, src2w);
+ return SLJIT_SUCCESS;
+ }
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src2 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+#else
+ if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
+#endif
+ BINARY_EAX_IMM(TEST_EAX_i32, src1w);
+ return SLJIT_SUCCESS;
+ }
+
+ if (!(src1 & SLJIT_IMM)) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src2w) || compiler->mode32) {
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = GROUP_F7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
+ inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = TEST_rm_r;
+ }
+#else
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = GROUP_F7;
+#endif
+ return SLJIT_SUCCESS;
+ }
+ else if (FAST_IS_REG(src1)) {
+ inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = TEST_rm_r;
+ return SLJIT_SUCCESS;
+ }
+ }
+
+ if (!(src2 & SLJIT_IMM)) {
+ if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src1w) || compiler->mode32) {
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = GROUP_F7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
+ inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = TEST_rm_r;
+ }
+#else
+ inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = GROUP_F7;
+#endif
+ return SLJIT_SUCCESS;
+ }
+ else if (FAST_IS_REG(src2)) {
+ inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = TEST_rm_r;
+ return SLJIT_SUCCESS;
+ }
+ }
+
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src2w) || compiler->mode32) {
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst = GROUP_F7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
+ inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst = TEST_rm_r;
+ }
+#else
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst = GROUP_F7;
+#endif
+ }
+ else {
+ inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
+ FAIL_IF(!inst);
+ *inst = TEST_rm_r;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_shift(struct sljit_compiler *compiler,
+ sljit_u8 mode,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_u8* inst;
+
+ if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {
+ if (dst == src1 && dstw == src1w) {
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);
+ FAIL_IF(!inst);
+ *inst |= mode;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst |= mode;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
+ return SLJIT_SUCCESS;
+ }
+ if (FAST_IS_REG(dst)) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);
+ FAIL_IF(!inst);
+ *inst |= mode;
+ return SLJIT_SUCCESS;
+ }
+
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst |= mode;
+ EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == SLJIT_PREF_SHIFT_REG) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
+ }
+ else if (FAST_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
+ if (src1 != dst)
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);
+ FAIL_IF(!inst);
+ *inst |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
+ }
+ else {
+ /* This case is really difficult, since ecx itself may used for
+ addressing, and we must ensure to work even in that case. */
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
+#else
+ /* [esp+0] contains the flags. */
+ EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0);
+#endif
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
+ FAIL_IF(!inst);
+ *inst |= mode;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
+#else
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw));
+#endif
+ EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler,
+ sljit_u8 mode, sljit_s32 set_flags,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ /* The CPU does not set flags if the shift count is 0. */
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#else
+ if ((src2w & 0x1f) != 0)
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#endif
+ if (!set_flags)
+ return emit_mov(compiler, dst, dstw, src1, src1w);
+ /* OR dst, src, 0 */
+ return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32,
+ dst, dstw, src1, src1w, SLJIT_IMM, 0);
+ }
+
+ if (!set_flags)
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+
+ if (!FAST_IS_REG(dst))
+ FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
+
+ FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
+
+ if (FAST_IS_REG(dst))
+ return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ CHECK_EXTRA_REGS(src1, src1w, (void)0);
+ CHECK_EXTRA_REGS(src2, src2w, (void)0);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = op & SLJIT_I32_OP;
+#endif
+
+ if (GET_OPCODE(op) >= SLJIT_MUL) {
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (!GET_FLAGS(op)) {
+ if (emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
+ return compiler->error;
+ }
+ else
+ compiler->flags_saved = 0;
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_ADDC:
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
+ FAIL_IF(emit_restore_flags(compiler, 1));
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
+ FAIL_IF(emit_save_flags(compiler));
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ return emit_cum_binary(compiler, ADC_r_rm, ADC_rm_r, ADC, ADC_EAX_i32,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SUB:
+ if (!GET_FLAGS(op)) {
+ if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
+ return compiler->error;
+ }
+ else
+ compiler->flags_saved = 0;
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ if (dst == SLJIT_UNUSED)
+ return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
+ return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SUBC:
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
+ FAIL_IF(emit_restore_flags(compiler, 1));
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
+ FAIL_IF(emit_save_flags(compiler));
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ return emit_non_cum_binary(compiler, SBB_r_rm, SBB_rm_r, SBB, SBB_EAX_i32,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_MUL:
+ return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_AND:
+ if (dst == SLJIT_UNUSED)
+ return emit_test_binary(compiler, src1, src1w, src2, src2w);
+ return emit_cum_binary(compiler, AND_r_rm, AND_rm_r, AND, AND_EAX_i32,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_OR:
+ return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_XOR:
+ return emit_cum_binary(compiler, XOR_r_rm, XOR_rm_r, XOR, XOR_EAX_i32,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SHL:
+ return emit_shift_with_flags(compiler, SHL, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_LSHR:
+ return emit_shift_with_flags(compiler, SHR, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_ASHR:
+ return emit_shift_with_flags(compiler, SAR, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (reg >= SLJIT_R3 && reg <= SLJIT_R6)
+ return -1;
+#endif
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ return reg;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ sljit_u8 *inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+ SLJIT_MEMCPY(inst, instruction, size);
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+/* Alignment + 2 * 16 bytes. */
+static sljit_s32 sse2_data[3 + (4 + 4) * 2];
+static sljit_s32 *sse2_buffer;
+
+static void init_compiler(void)
+{
+ sse2_buffer = (sljit_s32*)(((sljit_uw)sse2_data + 15) & ~0xf);
+ /* Single precision constants. */
+ sse2_buffer[0] = 0x80000000;
+ sse2_buffer[4] = 0x7fffffff;
+ /* Double precision constants. */
+ sse2_buffer[8] = 0;
+ sse2_buffer[9] = 0x80000000;
+ sse2_buffer[12] = 0xffffffff;
+ sse2_buffer[13] = 0x7fffffff;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+{
+#ifdef SLJIT_IS_FPU_AVAILABLE
+ return SLJIT_IS_FPU_AVAILABLE;
+#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
+ if (cpu_has_sse2 == -1)
+ get_cpu_features();
+ return cpu_has_sse2;
+#else /* SLJIT_DETECT_SSE2 */
+ return 1;
+#endif /* SLJIT_DETECT_SSE2 */
+}
+
+static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode,
+ sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w)
+{
+ sljit_u8 *inst;
+
+ inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = opcode;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 emit_sse2_logic(struct sljit_compiler *compiler, sljit_u8 opcode,
+ sljit_s32 pref66, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w)
+{
+ sljit_u8 *inst;
+
+ inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = opcode;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,
+ sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw)
+{
+ return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw);
+}
+
+static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,
+ sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src)
+{
+ return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw);
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+ sljit_u8 *inst;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)
+ compiler->mode32 = 0;
+#endif
+
+ inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = CVTTSD2SI_r_xm;
+
+ if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
+ return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;
+ sljit_u8 *inst;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)
+ compiler->mode32 = 0;
+#endif
+
+ if (src & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
+ srcw = (sljit_s32)srcw;
+#endif
+ EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = CVTSI2SD_x_rm;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ compiler->flags_saved = 0;
+ if (!FAST_IS_REG(src1)) {
+ FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
+ src1 = TMP_FREG;
+ }
+ return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_F32_OP), src1, src2, src2w);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_s32 dst_r;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ CHECK_ERROR();
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
+
+ if (GET_OPCODE(op) == SLJIT_MOV_F64) {
+ if (FAST_IS_REG(dst))
+ return emit_sse2_load(compiler, op & SLJIT_F32_OP, dst, src, srcw);
+ if (FAST_IS_REG(src))
+ return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, src);
+ FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src, srcw));
+ return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
+ }
+
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) {
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;
+ if (FAST_IS_REG(src)) {
+ /* We overwrite the high bits of source. From SLJIT point of view,
+ this is not an issue.
+ Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */
+ FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_F32_OP, src, src, 0));
+ }
+ else {
+ FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_F32_OP), TMP_FREG, src, srcw));
+ src = TMP_FREG;
+ }
+
+ FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_F32_OP, dst_r, src, 0));
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+ }
+
+ if (SLOW_IS_REG(dst)) {
+ dst_r = dst;
+ if (dst != src)
+ FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw));
+ }
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw));
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_NEG_F64:
+ FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer : sse2_buffer + 8)));
+ break;
+
+ case SLJIT_ABS_F64:
+ FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer + 4 : sse2_buffer + 12)));
+ break;
+ }
+
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 dst_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (FAST_IS_REG(dst)) {
+ dst_r = dst;
+ if (dst == src1)
+ ; /* Do nothing here. */
+ else if (dst == src2 && (op == SLJIT_ADD_F64 || op == SLJIT_MUL_F64)) {
+ /* Swap arguments. */
+ src2 = src1;
+ src2w = src1w;
+ }
+ else if (dst != src2)
+ FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src1, src1w));
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
+ }
+ }
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD_F64:
+ FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_SUB_F64:
+ FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_MUL_F64:
+ FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_DIV_F64:
+ FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
+ break;
+ }
+
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ sljit_u8 *inst;
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ /* We should restore the flags before the label,
+ since other taken jumps has their own flags as well. */
+ if (SLJIT_UNLIKELY(compiler->flags_saved))
+ PTR_FAIL_IF(emit_restore_flags(compiler, 0));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+
+ inst = (sljit_u8*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF(!inst);
+
+ *inst++ = 0;
+ *inst++ = 0;
+
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ sljit_u8 *inst;
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) {
+ if ((type & 0xff) <= SLJIT_JUMP)
+ PTR_FAIL_IF(emit_restore_flags(compiler, 0));
+ compiler->flags_saved = 0;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF_NULL(jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type >= SLJIT_CALL1)
+ PTR_FAIL_IF(call_with_args(compiler, type));
+
+ /* Worst case size. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
+#else
+ compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
+#endif
+
+ inst = (sljit_u8*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF_NULL(inst);
+
+ *inst++ = 0;
+ *inst++ = type + 2;
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8 *inst;
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) {
+ if (type <= SLJIT_JUMP)
+ FAIL_IF(emit_restore_flags(compiler, 0));
+ compiler->flags_saved = 0;
+ }
+
+ if (type >= SLJIT_CALL1) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (src == SLJIT_R2) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
+ src = TMP_REG1;
+ }
+ if (src == SLJIT_MEM1(SLJIT_SP) && type >= SLJIT_CALL3)
+ srcw += sizeof(sljit_sw);
+#endif
+#endif
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
+ if (src == SLJIT_R2) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
+ src = TMP_REG1;
+ }
+#endif
+ FAIL_IF(call_with_args(compiler, type));
+ }
+
+ if (src == SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF_NULL(jump);
+ set_jump(jump, compiler, JUMP_ADDR);
+ jump->u.target = srcw;
+
+ /* Worst case size. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->size += 5;
+#else
+ compiler->size += 10 + 3;
+#endif
+
+ inst = (sljit_u8*)ensure_buf(compiler, 2);
+ FAIL_IF_NULL(inst);
+
+ *inst++ = 0;
+ *inst++ = type + 2;
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+#endif
+ inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_FF;
+ *inst |= (type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm;
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_s32 type)
+{
+ sljit_u8 *inst;
+ sljit_u8 cond_set = 0;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ sljit_s32 reg;
+#else
+ /* CHECK_EXTRA_REGS migh overwrite these values. */
+ sljit_s32 dst_save = dst;
+ sljit_sw dstw_save = dstw;
+#endif
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+ SLJIT_UNUSED_ARG(srcw);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ if (SLJIT_UNLIKELY(compiler->flags_saved))
+ FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS));
+
+ type &= 0xff;
+ /* setcc = jcc + 0x10. */
+ cond_set = get_jump_code(type) + 0x10;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3);
+ FAIL_IF(!inst);
+ INC_SIZE(4 + 3);
+ /* Set low register to conditional flag. */
+ *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B;
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | reg_lmap[TMP_REG1];
+ *inst++ = REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B);
+ *inst++ = OR_rm8_r8;
+ *inst++ = MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst];
+ return SLJIT_SUCCESS;
+ }
+
+ reg = (op == SLJIT_MOV && FAST_IS_REG(dst)) ? dst : TMP_REG1;
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4 + 4);
+ /* Set low register to conditional flag. */
+ *inst++ = (reg_map[reg] <= 7) ? REX : REX_B;
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | reg_lmap[reg];
+ *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
+ *inst++ = GROUP_0F;
+ *inst++ = MOVZX_r_rm8;
+ *inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg];
+
+ if (reg != TMP_REG1)
+ return SLJIT_SUCCESS;
+
+ if (GET_OPCODE(op) < SLJIT_ADD) {
+ compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV;
+ return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
+ }
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG1, 0);
+#else /* SLJIT_CONFIG_X86_64 */
+ if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) {
+ if (reg_map[dst] <= 4) {
+ /* Low byte is accessible. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3);
+ FAIL_IF(!inst);
+ INC_SIZE(3 + 3);
+ /* Set low byte to conditional flag. */
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | reg_map[dst];
+
+ *inst++ = GROUP_0F;
+ *inst++ = MOVZX_r_rm8;
+ *inst = MOD_REG | (reg_map[dst] << 3) | reg_map[dst];
+ return SLJIT_SUCCESS;
+ }
+
+ /* Low byte is not accessible. */
+ if (cpu_has_cmov == -1)
+ get_cpu_features();
+
+ if (cpu_has_cmov) {
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);
+ /* a xor reg, reg operation would overwrite the flags. */
+ EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0);
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
+ FAIL_IF(!inst);
+ INC_SIZE(3);
+
+ *inst++ = GROUP_0F;
+ /* cmovcc = setcc - 0x50. */
+ *inst++ = cond_set - 0x50;
+ *inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1];
+ return SLJIT_SUCCESS;
+ }
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1 + 3 + 3 + 1);
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
+ /* Set al to conditional flag. */
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | 0 /* eax */;
+
+ *inst++ = GROUP_0F;
+ *inst++ = MOVZX_r_rm8;
+ *inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */;
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
+ return SLJIT_SUCCESS;
+ }
+
+ if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] == 0, scratch_reg1_must_be_eax);
+ if (dst != SLJIT_R0) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1 + 3 + 2 + 1);
+ /* Set low register to conditional flag. */
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | 0 /* eax */;
+ *inst++ = OR_rm8_r8;
+ *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst];
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
+ }
+ else {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(2 + 3 + 2 + 2);
+ /* Set low register to conditional flag. */
+ *inst++ = XCHG_r_rm;
+ *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1];
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | 1 /* ecx */;
+ *inst++ = OR_rm8_r8;
+ *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */;
+ *inst++ = XCHG_r_rm;
+ *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1];
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* Set TMP_REG1 to the bit. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1 + 3 + 3 + 1);
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
+ /* Set al to conditional flag. */
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | 0 /* eax */;
+
+ *inst++ = GROUP_0F;
+ *inst++ = MOVZX_r_rm8;
+ *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */;
+
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
+
+ if (GET_OPCODE(op) < SLJIT_ADD)
+ return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);
+#endif /* SLJIT_CONFIG_X86_64 */
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (NOT_HALFWORD(offset)) {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset));
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);
+ return compiler->error;
+#else
+ return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0);
+#endif
+ }
+#endif
+
+ if (offset != 0)
+ return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
+ return emit_mov(compiler, dst, dstw, SLJIT_SP, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ sljit_u8 *inst;
+ struct sljit_const *const_;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ sljit_s32 reg;
+#endif
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+ reg = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+
+ if (emit_load_imm64(compiler, reg, init_value))
+ return NULL;
+#else
+ if (dst == SLJIT_UNUSED)
+ dst = TMP_REG1;
+
+ if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
+ return NULL;
+#endif
+
+ inst = (sljit_u8*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF(!inst);
+
+ *inst++ = 0;
+ *inst++ = 1;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (dst & SLJIT_MEM)
+ if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
+ return NULL;
+#endif
+
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ SLJIT_UNUSED_ARG(executable_offset);
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);
+#else
+ sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ SLJIT_UNUSED_ARG(executable_offset);
+ sljit_unaligned_store_sw((void*)addr, new_constant);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void)
+{
+#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
+ if (cpu_has_sse2 == -1)
+ get_cpu_features();
+ return cpu_has_sse2;
+#else
+ return 1;
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void)
+{
+ if (cpu_has_cmov == -1)
+ get_cpu_features();
+ return cpu_has_cmov;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler,
+ sljit_s32 type,
+ sljit_s32 dst_reg,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8* inst;
+
+ CHECK_ERROR();
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(sljit_x86_is_cmov_available());
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_I32_OP));
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " x86_cmov%s %s%s, ",
+ !(dst_reg & SLJIT_I32_OP) ? "" : ".i",
+ jump_names[type & 0xff], JUMP_POSTFIX(type));
+ sljit_verbose_reg(compiler, dst_reg & ~SLJIT_I32_OP);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+
+ ADJUST_LOCAL_OFFSET(src, srcw);
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = dst_reg & SLJIT_I32_OP;
+#endif
+ dst_reg &= ~SLJIT_I32_OP;
+
+ if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
+ src = TMP_REG1;
+ srcw = 0;
+ }
+
+ inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw);
+ FAIL_IF(!inst);
+ *inst++ = GROUP_0F;
+ *inst = get_jump_code(type & 0xff) - 0x40;
+ return SLJIT_SUCCESS;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitUtils.c b/thirdparty/pcre2/src/sljit/sljitUtils.c
new file mode 100644
index 0000000000..ec5c321194
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitUtils.c
@@ -0,0 +1,337 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ------------------------------------------------------------------------ */
+/* Locks */
+/* ------------------------------------------------------------------------ */
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+static SLJIT_INLINE void allocator_grab_lock(void)
+{
+ /* Always successful. */
+}
+
+static SLJIT_INLINE void allocator_release_lock(void)
+{
+ /* Always successful. */
+}
+
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+{
+ /* Always successful. */
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+{
+ /* Always successful. */
+}
+
+#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+
+#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */
+
+#include "windows.h"
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+static HANDLE allocator_mutex = 0;
+
+static SLJIT_INLINE void allocator_grab_lock(void)
+{
+ /* No idea what to do if an error occures. Static mutexes should never fail... */
+ if (!allocator_mutex)
+ allocator_mutex = CreateMutex(NULL, TRUE, NULL);
+ else
+ WaitForSingleObject(allocator_mutex, INFINITE);
+}
+
+static SLJIT_INLINE void allocator_release_lock(void)
+{
+ ReleaseMutex(allocator_mutex);
+}
+
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+static HANDLE global_mutex = 0;
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+{
+ /* No idea what to do if an error occures. Static mutexes should never fail... */
+ if (!global_mutex)
+ global_mutex = CreateMutex(NULL, TRUE, NULL);
+ else
+ WaitForSingleObject(global_mutex, INFINITE);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+{
+ ReleaseMutex(global_mutex);
+}
+
+#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+
+#else /* _WIN32 */
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+#include <pthread.h>
+
+static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static SLJIT_INLINE void allocator_grab_lock(void)
+{
+ pthread_mutex_lock(&allocator_mutex);
+}
+
+static SLJIT_INLINE void allocator_release_lock(void)
+{
+ pthread_mutex_unlock(&allocator_mutex);
+}
+
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+#include <pthread.h>
+
+static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+{
+ pthread_mutex_lock(&global_mutex);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+{
+ pthread_mutex_unlock(&global_mutex);
+}
+
+#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+
+#endif /* _WIN32 */
+
+/* ------------------------------------------------------------------------ */
+/* Stack */
+/* ------------------------------------------------------------------------ */
+
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+#ifdef _WIN32
+#include "windows.h"
+#else
+/* Provides mmap function. */
+#include <sys/mman.h>
+/* For detecting the page size. */
+#include <unistd.h>
+
+#ifndef MAP_ANON
+
+#include <fcntl.h>
+
+/* Some old systems does not have MAP_ANON. */
+static sljit_s32 dev_zero = -1;
+
+#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
+
+static SLJIT_INLINE sljit_s32 open_dev_zero(void)
+{
+ dev_zero = open("/dev/zero", O_RDWR);
+ return dev_zero < 0;
+}
+
+#else /* SLJIT_SINGLE_THREADED */
+
+#include <pthread.h>
+
+static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static SLJIT_INLINE sljit_s32 open_dev_zero(void)
+{
+ pthread_mutex_lock(&dev_zero_mutex);
+ /* The dev_zero might be initialized by another thread during the waiting. */
+ if (dev_zero < 0) {
+ dev_zero = open("/dev/zero", O_RDWR);
+ }
+ pthread_mutex_unlock(&dev_zero_mutex);
+ return dev_zero < 0;
+}
+
+#endif /* SLJIT_SINGLE_THREADED */
+
+#endif
+
+#endif
+
+#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
+
+/* Planning to make it even more clever in the future. */
+static sljit_sw sljit_page_align = 0;
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data)
+{
+ struct sljit_stack *stack;
+ union {
+ void *ptr;
+ sljit_uw uw;
+ } base;
+#ifdef _WIN32
+ SYSTEM_INFO si;
+#endif
+
+ SLJIT_UNUSED_ARG(allocator_data);
+ if (limit > max_limit || limit < 1)
+ return NULL;
+
+#ifdef _WIN32
+ if (!sljit_page_align) {
+ GetSystemInfo(&si);
+ sljit_page_align = si.dwPageSize - 1;
+ }
+#else
+ if (!sljit_page_align) {
+ sljit_page_align = sysconf(_SC_PAGESIZE);
+ /* Should never happen. */
+ if (sljit_page_align < 0)
+ sljit_page_align = 4096;
+ sljit_page_align--;
+ }
+#endif
+
+ /* Align limit and max_limit. */
+ max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
+
+ stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
+ if (!stack)
+ return NULL;
+
+#ifdef _WIN32
+ base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE);
+ if (!base.ptr) {
+ SLJIT_FREE(stack, allocator_data);
+ return NULL;
+ }
+ stack->base = base.uw;
+ stack->limit = stack->base;
+ stack->max_limit = stack->base + max_limit;
+ if (sljit_stack_resize(stack, stack->base + limit)) {
+ sljit_free_stack(stack, allocator_data);
+ return NULL;
+ }
+#else
+#ifdef MAP_ANON
+ base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+#else
+ if (dev_zero < 0) {
+ if (open_dev_zero()) {
+ SLJIT_FREE(stack, allocator_data);
+ return NULL;
+ }
+ }
+ base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
+#endif
+ if (base.ptr == MAP_FAILED) {
+ SLJIT_FREE(stack, allocator_data);
+ return NULL;
+ }
+ stack->base = base.uw;
+ stack->limit = stack->base + limit;
+ stack->max_limit = stack->base + max_limit;
+#endif
+ stack->top = stack->base;
+ return stack;
+}
+
+#undef PAGE_ALIGN
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack, void *allocator_data)
+{
+ SLJIT_UNUSED_ARG(allocator_data);
+#ifdef _WIN32
+ VirtualFree((void*)stack->base, 0, MEM_RELEASE);
+#else
+ munmap((void*)stack->base, stack->max_limit - stack->base);
+#endif
+ SLJIT_FREE(stack, allocator_data);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
+{
+ sljit_uw aligned_old_limit;
+ sljit_uw aligned_new_limit;
+
+ if ((new_limit > stack->max_limit) || (new_limit < stack->base))
+ return -1;
+#ifdef _WIN32
+ aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
+ aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
+ if (aligned_new_limit != aligned_old_limit) {
+ if (aligned_new_limit > aligned_old_limit) {
+ if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
+ return -1;
+ }
+ else {
+ if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
+ return -1;
+ }
+ }
+ stack->limit = new_limit;
+ return 0;
+#else
+ if (new_limit >= stack->limit) {
+ stack->limit = new_limit;
+ return 0;
+ }
+ aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
+ aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
+ /* If madvise is available, we release the unnecessary space. */
+#if defined(MADV_DONTNEED)
+ if (aligned_new_limit < aligned_old_limit)
+ madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
+#elif defined(POSIX_MADV_DONTNEED)
+ if (aligned_new_limit < aligned_old_limit)
+ posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED);
+#endif
+ stack->limit = new_limit;
+ return 0;
+#endif
+}
+
+#endif /* SLJIT_UTIL_STACK */
+
+#endif