Merge remote-tracking branch 'es/master' into enrich

This commit is contained in:
Martijn van Groningen 2019-09-30 08:12:07 +02:00
commit 197c1d59d4
No known key found for this signature in database
GPG key ID: AB236F4FCF2AF12A
197 changed files with 2065 additions and 1787 deletions

View file

@ -11,7 +11,7 @@
[id="{upid}-{api}-request"]
==== Execution
{stack-ov}/actions.html#actions-ack-throttle[Acknowledging a watch] enables you
{ref}/actions.html#actions-ack-throttle[Acknowledging a watch] enables you
to manually throttle execution of a watch's actions. A watch can be acknowledged
through the following request:

View file

@ -49,9 +49,9 @@ specialized code may define new ways to use a Painless script.
| Bucket selector aggregation | <<painless-bucket-selector-agg-context, Painless Documentation>>
| {ref}/search-aggregations-pipeline-bucket-selector-aggregation.html[Elasticsearch Documentation]
| Watcher condition | <<painless-watcher-condition-context, Painless Documentation>>
| {xpack-ref}/condition-script.html[Elasticsearch Documentation]
| {ref}/condition-script.html[Elasticsearch Documentation]
| Watcher transform | <<painless-watcher-transform-context, Painless Documentation>>
| {xpack-ref}/transform-script.html[Elasticsearch Documentation]
| {ref}/transform-script.html[Elasticsearch Documentation]
|====
include::painless-contexts/index.asciidoc[]

View file

@ -1,7 +1,7 @@
[[painless-watcher-condition-context]]
=== Watcher condition context
Use a Painless script as a {xpack-ref}/condition-script.html[watch condition]
Use a Painless script as a {ref}/condition-script.html[watch condition]
that determines whether to execute a watch or a particular action within a watch.
Condition scripts return a Boolean value to indicate the status of the condition.

View file

@ -29,7 +29,7 @@ The following variables are available in all watcher contexts.
`ctx['payload']` (`Map`, read-only)::
The accessible watch data based upon the
{xpack-ref}/input.html[watch input].
{ref}/input.html[watch input].
*API*

View file

@ -1,7 +1,7 @@
[[painless-watcher-transform-context]]
=== Watcher transform context
Use a Painless script as a {xpack-ref}/transform-script.html[watch transform]
Use a Painless script as a {ref}/transform-script.html[watch transform]
to transform a payload into a new payload for further use in the watch.
Transform scripts return an Object value of the new payload.

View file

@ -1,7 +1,7 @@
[[analysis-icu]]
=== ICU Analysis Plugin
The ICU Analysis plugin integrates the Lucene ICU module into elasticsearch,
The ICU Analysis plugin integrates the Lucene ICU module into {es},
adding extended Unicode support using the http://site.icu-project.org/[ICU]
libraries, including better analysis of Asian languages, Unicode
normalization, Unicode-aware case folding, collation support, and

View file

@ -44,7 +44,7 @@ The API returns the following response:
["source","txt",subs="attributes,callouts"]
------------------------------------------------------------------------------
name component version description
U7321H6 analysis-icu {version_qualified} The ICU Analysis plugin integrates Lucene ICU module into elasticsearch, adding ICU relates analysis components.
U7321H6 analysis-icu {version_qualified} The ICU Analysis plugin integrates the Lucene ICU module into Elasticsearch, adding ICU-related analysis components.
U7321H6 analysis-kuromoji {version_qualified} The Japanese (kuromoji) Analysis plugin integrates Lucene kuromoji analysis module into elasticsearch.
U7321H6 analysis-nori {version_qualified} The Korean (nori) Analysis plugin integrates Lucene nori analysis module into elasticsearch.
U7321H6 analysis-phonetic {version_qualified} The Phonetic Analysis plugin integrates phonetic token filter analysis with elasticsearch.

View file

@ -13,6 +13,8 @@ to the <<indices-recovery, indices recovery>> API.
`GET /_cat/recovery/<index>`
`GET /_cat/recovery`
[[cat-recovery-api-desc]]
==== {api-description-title}
@ -37,14 +39,20 @@ include::{docdir}/rest-api/common-parms.asciidoc[tag=index]
[[cat-recovery-query-params]]
==== {api-query-parms-title}
include::{docdir}/rest-api/common-parms.asciidoc[tag=active-only]
include::{docdir}/rest-api/common-parms.asciidoc[tag=bytes]
include::{docdir}/rest-api/common-parms.asciidoc[tag=detailed]
include::{docdir}/rest-api/common-parms.asciidoc[tag=http-format]
include::{docdir}/rest-api/common-parms.asciidoc[tag=cat-h]
include::{docdir}/rest-api/common-parms.asciidoc[tag=help]
include::{docdir}/rest-api/common-parms.asciidoc[tag=index-query-parm]
include::{docdir}/rest-api/common-parms.asciidoc[tag=local]
include::{docdir}/rest-api/common-parms.asciidoc[tag=master-timeout]

View file

@ -21,7 +21,8 @@ bin/elasticsearch-syskeygen
The command generates a `system_key` file, which you can use to symmetrically
encrypt sensitive data. For example, you can use this key to prevent {watcher}
from returning and storing information that contains clear text credentials. See {xpack-ref}/encrypting-data.html[Encrypting sensitive data in {watcher}].
from returning and storing information that contains clear text credentials. See
<<encrypting-data>>.
IMPORTANT: The system key is a symmetric key, so the same key must be used on
every node in the cluster.

View file

@ -80,7 +80,7 @@ The top-level keys that the policy supports are described below:
| `schedule` | A periodic or absolute time schedule. Supports all values
supported by the cron scheduler:
{xpack-ref}/trigger-schedule.html#schedule-cron[Cron scheduler configuration]
<<schedule-cron,Cron scheduler configuration>>
| `name` | A name automatically given to each snapshot performed by this policy.
Supports the same <<date-math-index-names,date math>> supported in index

View file

@ -97,7 +97,7 @@ PUT /_slm/policy/nightly-snapshots
--------------------------------------------------
// TEST[continued]
<1> when the snapshot should be taken, using
{xpack-ref}/trigger-schedule.html#schedule-cron[Cron syntax], in this
<<schedule-cron,Cron syntax>>, in this
case at 1:30AM each day
<2> whe name each snapshot should be given, using
<<date-math-index-names,date math>> to include the current date in the name

View file

@ -28,7 +28,7 @@ this scenario:
If the master had just waited for a few minutes, then the missing shards could
have been re-allocated to Node 5 with the minimum of network traffic. This
process would be even quicker for idle shards (shards not receiving indexing
requests) which have been automatically <<synced-flush-api,sync-flushed>>.
requests) which have been automatically <<indices-synced-flush-api,sync-flushed>>.
The allocation of replica shards which become unassigned because a node has
left can be delayed with the `index.unassigned.node_left.delayed_timeout`

View file

@ -52,6 +52,8 @@ include::high-availability.asciidoc[]
include::security/index.asciidoc[]
include::{xes-repo-dir}/watcher/index.asciidoc[]
include::commands/index.asciidoc[]
include::how-to.asciidoc[]

View file

@ -1,5 +1,32 @@
[[indices-flush]]
=== Flush
=== Flush API
++++
<titleabbrev>Flush</titleabbrev>
++++
Flushes one or more indices.
[source,console]
--------------------------------------------------
POST /twitter/_flush
--------------------------------------------------
// TEST[setup:twitter]
[[flush-api-request]]
==== {api-request-title}
`POST /<index>/flush`
`GET /<index>/flush`
`POST /flush`
`GET /flush`
[[flush-api-desc]]
==== {api-description-title}
Flushing an index is the process of making sure that any data that is currently
only stored in the <<index-modules-translog,transaction log>> is also
@ -22,47 +49,90 @@ call the flush API after indexing some documents then a successful response
indicates that {es} has flushed all the documents that were indexed before the
flush API was called.
[[flush-api-path-params]]
==== {api-path-parms-title}
include::{docdir}/rest-api/common-parms.asciidoc[tag=index]
+
To flush all indices,
omit this parameter
or use a value of `_all` or `*`.
[[flush-api-query-params]]
==== {api-query-parms-title}
include::{docdir}/rest-api/common-parms.asciidoc[tag=allow-no-indices]
include::{docdir}/rest-api/common-parms.asciidoc[tag=expand-wildcards]
+
Defaults to `open`.
`force`::
+
--
(Optional, boolean)
If `true`,
the request forces a flush
even if there are no changes to commit to the index.
Defaults to `true`.
You can use this parameter
to increment the generation number of the transaction log.
This parameter is considered internal.
--
include::{docdir}/rest-api/common-parms.asciidoc[tag=index-ignore-unavailable]
`wait_if_ongoing`::
+
--
(Optional, boolean)
If `true`,
the flush operation blocks until execution
when another flush operation is running.
If `false`,
{es} returns an error
if you request a flush
when another flush operation is running.
Defaults to `true`.
--
[[flush-api-example]]
==== {api-examples-title}
[[flush-api-specific-ex]]
===== Flush a specific index
[source,console]
--------------------------------------------------
POST twitter/_flush
--------------------------------------------------
// TEST[setup:twitter]
----
POST /kimchy/_flush
----
// TEST[s/^/PUT kimchy\n/]
[float]
[[flush-parameters]]
==== Request Parameters
The flush API accepts the following request parameters:
[horizontal]
`wait_if_ongoing`:: If set to `true` the flush operation will block until the
flush can be executed if another flush operation is already executing. If set to
`false` then an exception will be thrown on the shard level if another flush
operation is already running. Defaults to `true`.
`force`:: Whether a flush should be forced even if it is not necessarily needed
i.e. if no changes will be committed to the index. This can be used to force
the generation number of the transaction log to be incremented even if no
uncommitted changes are present. This parameter should be considered internal.
[float]
[[flush-multi-index]]
==== Multi Index
The flush API can be applied to more than one index with a single call, or even
on `_all` the indices.
===== Flush several indices
[source,console]
--------------------------------------------------
POST kimchy,elasticsearch/_flush
POST _flush
--------------------------------------------------
----
POST /kimchy,elasticsearch/_flush
----
// TEST[s/^/PUT kimchy\nPUT elasticsearch\n/]
[float]
[[synced-flush-api]]
==== Synced Flush
[[flush-api-all-ex]]
===== Flush all indices
See <<indices-synced-flush-api>>.
[source,console]
----
POST /_flush
----

View file

@ -107,7 +107,7 @@ cluster that stores the monitoring data must have at least one
<<ingest,ingest node>>.
For more information about typical monitoring architectures,
see {stack-ov}/how-monitoring-works.html[How Monitoring Works].
see <<how-monitoring-works>>.
--
. If you choose to use an `http` exporter:

View file

@ -140,4 +140,4 @@ related to monitoring data, which can be very useful when there are a large
number of Logstash nodes or Beats.
For more information about typical monitoring architectures, see
{xpack-ref}/how-monitoring-works.html[How Monitoring Works].
<<how-monitoring-works>>.

View file

@ -23,7 +23,7 @@ TIP: In production environments, we strongly recommend using a separate cluster
monitoring cluster prevents production cluster outages from impacting your
ability to access your monitoring data. It also prevents monitoring activities
from impacting the performance of your production cluster. See
{stack-ov}/monitoring-production.html[Monitoring in a production environment].
<<monitoring-production>>.
--

View file

@ -10,12 +10,14 @@ performance of your {es} cluster.
* <<monitoring-overview>>
* <<how-monitoring-works>>
* <<monitoring-production>>
* <<collecting-monitoring-data>>
* <<configuring-metricbeat>>
* <<configuring-filebeat>>
* <<config-monitoring-indices>>
* <<es-monitoring-collectors>>
* <<es-monitoring-exporters>>
* <<monitoring-troubleshooting>>
--
@ -23,6 +25,8 @@ include::overview.asciidoc[]
include::how-monitoring-works.asciidoc[]
include::production.asciidoc[]
include::collecting-monitoring-data.asciidoc[]
include::pause-export.asciidoc[]
@ -37,3 +41,5 @@ include::collectors.asciidoc[]
include::exporters.asciidoc[]
include::local-export.asciidoc[]
include::http-export.asciidoc[]
include::troubleshooting.asciidoc[]

View file

@ -0,0 +1,124 @@
[role="xpack"]
[[monitoring-production]]
== Monitoring in a production environment
In production, you should send monitoring data to a separate _monitoring cluster_
so that historical data is available even when the nodes you are monitoring are
not. For example, you can use {metricbeat} to ship monitoring data about {kib},
{es}, {ls}, and Beats to the monitoring cluster.
//If you are sending your data to the {esms-init}, see <<esms>>.
If you have at least a gold license, using a dedicated monitoring cluster also
enables you to monitor multiple clusters from a central location.
To store monitoring data in a separate cluster:
. Set up the {es} cluster you want to use as the monitoring cluster.
For example, you might set up a two host cluster with the nodes `es-mon-1` and
`es-mon-2`.
+
--
[IMPORTANT]
===============================
* To monitor an {es} {major-version} cluster, you must run {es} {major-version}
on the monitoring cluster.
* There must be at least one <<ingest,ingest node>> in the monitoring
cluster; it does not need to be a dedicated ingest node.
===============================
--
.. (Optional) Verify that the collection of monitoring data is disabled on the
monitoring cluster. By default, the `xpack.monitoring.collection.enabled` setting
is `false`.
+
--
For example, you can use the following APIs to review and change this setting:
[source,console]
----------------------------------
GET _cluster/settings
PUT _cluster/settings
{
"persistent": {
"xpack.monitoring.collection.enabled": false
}
}
----------------------------------
// TEST[skip:security errs]
--
.. If the {es} {security-features} are enabled on the monitoring cluster, create
users that can send and retrieve monitoring data.
+
--
NOTE: If you plan to use {kib} to view monitoring data, username and password
credentials must be valid on both the {kib} server and the monitoring cluster.
--
*** If you plan to use {metricbeat} to collect data about {es} or {kib},
create a user that has the `remote_monitoring_collector` built-in role and a
user that has the `remote_monitoring_agent`
{stack-ov}/built-in-roles.html#built-in-roles-remote-monitoring-agent[built-in role]. Alternatively, use the
`remote_monitoring_user` {stack-ov}/built-in-users.html[built-in user].
*** If you plan to use HTTP exporters to route data through your production
cluster, create a user that has the `remote_monitoring_agent`
{stack-ov}/built-in-roles.html#built-in-roles-remote-monitoring-agent[built-in role].
+
--
For example, the
following request creates a `remote_monitor` user that has the
`remote_monitoring_agent` role:
[source, sh]
---------------------------------------------------------------
POST /_security/user/remote_monitor
{
"password" : "changeme",
"roles" : [ "remote_monitoring_agent"],
"full_name" : "Internal Agent For Remote Monitoring"
}
---------------------------------------------------------------
// CONSOLE
// TEST[skip:needs-gold+-license]
Alternatively, use the `remote_monitoring_user` {stack-ov}/built-in-users.html[built-in user].
--
. Configure your production cluster to collect data and send it to the
monitoring cluster.
** <<configuring-metricbeat,Use {metricbeat}>>.
** <<configuring-monitoring,Use HTTP exporters>>.
. (Optional)
{logstash-ref}/configuring-logstash.html[Configure {ls} to collect data and send it to the monitoring cluster].
. (Optional) Configure the Beats to collect data and send it to the monitoring
cluster.
** {auditbeat-ref}/monitoring.html[Auditbeat]
** {filebeat-ref}/monitoring.html[Filebeat]
** {heartbeat-ref}/monitoring.html[Heartbeat]
** {metricbeat-ref}/monitoring.html[Metricbeat]
** {packetbeat-ref}/monitoring.html[Packetbeat]
** {winlogbeat-ref}/monitoring.html[Winlogbeat]
. (Optional) Configure {kib} to collect data and send it to the monitoring cluster:
** {kibana-ref}/monitoring-metricbeat.html[Use {metricbeat}].
** {kibana-ref}/monitoring-kibana.html[Use HTTP exporters].
. (Optional) Create a dedicated {kib} instance for monitoring, rather than using
a single {kib} instance to access both your production cluster and monitoring
cluster.
.. (Optional) Disable the collection of monitoring data in this {kib} instance.
Set the `xpack.monitoring.kibana.collection.enabled` setting to `false` in the
`kibana.yml` file. For more information about this setting, see
{kibana-ref}/monitoring-settings-kb.html[Monitoring settings in {kib}].
. {kibana-ref}/monitoring-data.html[Configure {kib} to retrieve and display the monitoring data].

View file

@ -0,0 +1,29 @@
[[monitoring-troubleshooting]]
== Troubleshooting monitoring
++++
<titleabbrev>Troubleshooting</titleabbrev>
++++
Use the information in this section to troubleshoot common problems and find
answers for frequently asked questions. See also
{logstash-ref}/monitoring-troubleshooting.html[Troubleshooting monitoring in {ls}].
For issues that you cannot fix yourself … were here to help.
If you are an existing Elastic customer with a support contract, please create
a ticket in the
https://support.elastic.co/customers/s/login/[Elastic Support portal].
Or post in the https://discuss.elastic.co/[Elastic forum].
*Symptoms*:
There is no information about your cluster on the *Stack Monitoring* page in
{kib}.
*Resolution*:
Check whether the appropriate indices exist on the monitoring cluster. For
example, use the <<cat-indices,cat indices>> command to verify that
there is a `.monitoring-kibana*` index for your {kib} monitoring data and a
`.monitoring-es*` index for your {es} monitoring data. If you are collecting
monitoring data by using {metricbeat} the indices have `-mb` in their names. If
the indices do not exist, review your configuration. For example, see
<<monitoring-production>>.

View file

@ -779,7 +779,7 @@ See <<explain-analyze-api>>.
[role="exclude",id="indices-synced-flush"]
=== Synced flush API
See <<synced-flush-api>>.
See <<indices-synced-flush-api>>.
[role="exclude",id="_repositories"]
=== Snapshot repositories

View file

@ -1,4 +1,12 @@
tag::active-only[]
`active_only`::
(Optional, boolean)
If `true`,
the response only includes ongoing shard recoveries.
Defaults to `false`.
end::active-only[]
tag::index-alias[]
Comma-separated list or wildcard expression of index alias names
used to limit the request.
@ -67,6 +75,14 @@ tag::default_operator[]
Defaults to `OR`.
end::default_operator[]
tag::detailed[]
`detailed`::
(Optional, boolean)
If `true`,
the response includes detailed information about shard recoveries.
Defaults to `false`.
end::detailed[]
tag::df[]
`df`::
(Optional, string) Field to use as default where no field prefix is
@ -232,6 +248,13 @@ tag::include-unloaded-segments[]
that are **not** loaded into memory. Defaults to `false`.
end::include-unloaded-segments[]
tag::index-query-parm[]
`index`::
(Optional, string)
Comma-separated list or wildcard expression of index names
used to limit the request.
end::index-query-parm[]
tag::index[]
`<index>`::
(Optional, string) Comma-separated list or wildcard expression of index names

View file

@ -117,9 +117,9 @@ the `http` exporter will not be deleted automatically.
Configures where the agent stores monitoring data. By default, the agent uses a
local exporter that indexes monitoring data on the cluster where it is installed.
Use an HTTP exporter to send data to a separate monitoring cluster. For more
information, see <<local-exporter-settings,Local Exporter Settings>>,
<<http-exporter-settings,HTTP Exporter Settings>>, and
{xpack-ref}/how-monitoring-works.html[How Monitoring Works].
information, see <<local-exporter-settings,Local exporter settings>>,
<<http-exporter-settings,HTTP exporter settings>>, and
<<how-monitoring-works>>.
[float]
[[local-exporter-settings]]

View file

@ -27,14 +27,12 @@ Set to `false` to disable {watcher} on the node.
`xpack.watcher.encrypt_sensitive_data`::
Set to `true` to encrypt sensitive data. If this setting is enabled, you
must also specify the `xpack.watcher.encryption_key` setting. For more
information, see
{xpack-ref}/encrypting-data.html[Encrypting sensitive data in {watcher}].
information, see <<encrypting-data>>.
`xpack.watcher.encryption_key` (<<secure-settings,Secure>>)::
Specifies the path to a file that contains a key for encrypting sensitive data.
If `xpack.watcher.encrypt_sensitive_data` is set to `true`, this setting is
required. For more information, see
{xpack-ref}/encrypting-data.html[Encrypting sensitive data in {watcher}].
required. For more information, see <<encrypting-data>>.
`xpack.watcher.history.cleaner_service.enabled`::
added:[6.3.0,Default changed to `true`.]
@ -88,7 +86,7 @@ include::ssl-settings.asciidoc[]
==== Email Notification Settings
You can configure the following email notification settings in
`elasticsearch.yml`. For more information about sending notifications
via email, see {xpack-ref}/actions-email.html#configuring-email-actions[Configuring Email].
via email, see <<configuring-email-actions>>.
`xpack.notification.email.account`::
Specifies account information for sending notifications via email. You
@ -98,14 +96,15 @@ can specify the following email account attributes:
[[email-account-attributes]]
`profile` (<<cluster-update-settings,Dynamic>>);;
The {xpack-ref}/actions-email.html#configuring-email[email profile] to use to build the MIME
The <<configuring-email,email profile>> to use to build the MIME
messages that are sent from the account. Valid values: `standard`, `gmail` and
`outlook`. Defaults to `standard`.
`email_defaults.*` (<<cluster-update-settings,Dynamic>>);;
An optional set of email attributes to use as defaults
for the emails sent from the account. See {xpack-ref}/actions-email.html#email-action-attributes[
Email Action Attributes] for the supported attributes.
for the emails sent from the account. See
<<email-action-attributes>> for the supported
attributes.
`smtp.auth` (<<cluster-update-settings,Dynamic>>);;
Set to `true` to attempt to authenticate the user using the
@ -166,9 +165,9 @@ can specify the following email account attributes:
`xpack.notification.email.html.sanitization.allow`::
Specifies the HTML elements that are allowed in email notifications. For
more information, see {xpack-ref}/actions-email.html#email-html-sanitization[Configuring HTML
Sanitization Options]. You can specify individual HTML elements
and the following HTML feature groups:
more information, see
<<email-html-sanitization>>. You can
specify individual HTML elements and the following HTML feature groups:
+
--
[[html-feature-groups]]
@ -229,7 +228,7 @@ include::ssl-settings.asciidoc[]
==== Slack Notification Settings
You can configure the following Slack notification settings in
`elasticsearch.yml`. For more information about sending notifications
via Slack, see {xpack-ref}/actions-slack.html#configuring-slack-actions[Configuring Slack].
via Slack, see <<configuring-slack-actions>>.
`xpack.notification.slack` ::
Specifies account information for sending notifications
@ -270,7 +269,7 @@ via Slack. You can specify the following Slack account attributes:
==== Jira Notification Settings
You can configure the following Jira notification settings in
`elasticsearch.yml`. For more information about using notifications
to create issues in Jira, see {xpack-ref}/actions-jira.html#configuring-jira-actions[Configuring Jira].
to create issues in Jira, see <<configuring-jira-actions>>.
`xpack.notification.jira` ::
Specifies account information for using notifications to create
@ -290,7 +289,7 @@ issues in Jira. You can specify the following Jira account attributes:
`issue_defaults`;;
Default fields values for the issue created in Jira. See
{xpack-ref}/actions-jira.html#jira-action-attributes[Jira Action Attributes] for more information.
<<jira-action-attributes>> for more information.
Optional.
--
@ -299,7 +298,7 @@ issues in Jira. You can specify the following Jira account attributes:
==== PagerDuty Notification Settings
You can configure the following PagerDuty notification settings in
`elasticsearch.yml`. For more information about sending notifications
via PagerDuty, see {xpack-ref}/actions-pagerduty.html#configuring-pagerduty-actions[Configuring PagerDuty].
via PagerDuty, see <<configuring-pagerduty-actions>>.
[[pagerduty-account-attributes]]
@ -318,8 +317,9 @@ PagerDuty API key] to use to access PagerDuty. Required.
--
+
`event_defaults`;;
Default values for {xpack-ref}/actions-pagerduty.html#pagerduty-event-trigger-incident-attributes[
PagerDuty event attributes]. Optional.
Default values for
<<pagerduty-event-trigger-incident-attributes,PagerDuty event attributes>>.
Optional.
+
--
`description`::

View file

@ -14,8 +14,7 @@ If you use {watcher} and have chosen to encrypt sensitive data (by setting
the secure settings store.
To pass this bootstrap check, you must set the `xpack.watcher.encryption_key`
on each node in the cluster. For more information, see
{xpack-ref}/encrypting-data.html[Encrypting Sensitive Data in {watcher}].
on each node in the cluster. For more information, see <<encrypting-data>>.
[float]
=== PKI realm check

View file

@ -249,7 +249,7 @@ Currently, using a _precision_ greater than 3 doesn't make any difference to the
function as the maximum number of second fractional digits returned is 3 (milliseconds).
[[sql-functions-datetime-trunc]]
==== `DATE_TRUNC`
==== `DATE_TRUNC/DATETRUNC`
.Synopsis:
[source, sql]
@ -269,7 +269,7 @@ DATE_TRUNC(
.Description:
Truncate the date/datetime to the specified unit by setting all fields that are less significant than the specified
one to zero (or one, for day, day of week and month).
one to zero (or one, for day, day of week and month). If any of the two arguments is `null` a `null` is returned.
[cols="^,^"]
|===

View file

@ -20,7 +20,7 @@ include::disable-shard-alloc.asciidoc[]
. *Stop indexing and perform a synced flush.*
+
--
Performing a <<synced-flush-api, synced-flush>> speeds up shard
Performing a <<indices-synced-flush-api, synced-flush>> speeds up shard
recovery.
include::synced-flush.asciidoc[]

View file

@ -30,7 +30,7 @@ include::disable-shard-alloc.asciidoc[]
--
While you can continue indexing during the upgrade, shard recovery
is much faster if you temporarily stop non-essential indexing and perform a
<<synced-flush-api, synced-flush>>.
<<indices-synced-flush-api, synced-flush>>.
include::synced-flush.asciidoc[]
@ -130,7 +130,7 @@ As soon as another node is upgraded, the replicas can be assigned and the
status will change to `green`.
====================================================
Shards that were not <<synced-flush-api,sync-flushed>> might take longer to
Shards that were not <<indices-synced-flush-api,sync-flushed>> might take longer to
recover. You can monitor the recovery status of individual shards by
submitting a <<cat-recovery,`_cat/recovery`>> request:

View file

@ -0,0 +1,101 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.painless;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.TraceClassVisitor;
import java.io.Closeable;
import java.util.BitSet;
/**
* Manages the top level writers for class and possibly
* clinit if necessary.
*/
public class ClassWriter implements Closeable {
protected final CompilerSettings compilerSettings;
protected final BitSet statements;
protected final org.objectweb.asm.ClassWriter classWriter;
protected final ClassVisitor classVisitor;
protected MethodWriter clinitWriter = null;
public ClassWriter(CompilerSettings compilerSettings, BitSet statements, Printer debugStream,
Class<?> baseClass, int classFrames, int classAccess, String className, String[] classInterfaces) {
this.compilerSettings = compilerSettings;
this.statements = statements;
classWriter = new org.objectweb.asm.ClassWriter(classFrames);
ClassVisitor visitor = classWriter;
if (compilerSettings.isPicky()) {
visitor = new SimpleChecksAdapter(visitor);
}
if (debugStream != null) {
visitor = new TraceClassVisitor(visitor, debugStream, null);
}
classVisitor = visitor;
classVisitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null,
Type.getType(baseClass).getInternalName(), classInterfaces);
}
public ClassVisitor getClassVisitor() {
return classVisitor;
}
/**
* Lazy loads the {@link MethodWriter} for clinit, so that if it's not
* necessary the method is never created for the class.
*/
public MethodWriter getClinitWriter() {
if (clinitWriter == null) {
clinitWriter = new MethodWriter(Opcodes.ACC_STATIC, WriterConstants.CLINIT, classVisitor, statements, compilerSettings);
clinitWriter.visitCode();
}
return clinitWriter;
}
public MethodWriter newMethodWriter(int access, Method method) {
return new MethodWriter(access, method, classVisitor, statements, compilerSettings);
}
@Override
public void close() {
if (clinitWriter != null) {
clinitWriter.returnValue();
clinitWriter.endMethod();
}
classVisitor.visitEnd();
}
public byte[] getClassBytes() {
return classWriter.toByteArray();
}
}

View file

@ -1,13 +1,17 @@
// ANTLR GENERATED CODE: DO NOT EDIT
package org.elasticsearch.painless.antlr;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.RuntimeMetaData;
import org.antlr.v4.runtime.Vocabulary;
import org.antlr.v4.runtime.VocabularyImpl;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
abstract class PainlessLexer extends Lexer {

View file

@ -1,13 +1,25 @@
// ANTLR GENERATED CODE: DO NOT EDIT
package org.elasticsearch.painless.antlr;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.FailedPredicateException;
import org.antlr.v4.runtime.NoViableAltException;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.RuntimeMetaData;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.Vocabulary;
import org.antlr.v4.runtime.VocabularyImpl;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.atn.ParserATNSimulator;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
import org.antlr.v4.runtime.tree.TerminalNode;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
class PainlessParser extends Parser {

View file

@ -141,6 +141,7 @@ import org.elasticsearch.painless.node.PField;
import org.elasticsearch.painless.node.SBlock;
import org.elasticsearch.painless.node.SBreak;
import org.elasticsearch.painless.node.SCatch;
import org.elasticsearch.painless.node.SClass;
import org.elasticsearch.painless.node.SContinue;
import org.elasticsearch.painless.node.SDeclBlock;
import org.elasticsearch.painless.node.SDeclaration;
@ -152,7 +153,6 @@ import org.elasticsearch.painless.node.SFunction;
import org.elasticsearch.painless.node.SIf;
import org.elasticsearch.painless.node.SIfElse;
import org.elasticsearch.painless.node.SReturn;
import org.elasticsearch.painless.node.SClass;
import org.elasticsearch.painless.node.SThrow;
import org.elasticsearch.painless.node.STry;
import org.elasticsearch.painless.node.SWhile;

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -75,7 +76,7 @@ public abstract class ANode {
/**
* Writes ASM based on the data collected during the analysis phase.
*/
abstract void write(MethodWriter writer, Globals globals);
abstract void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals);
/**
* Create an error with location information pointing to this node.

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
@ -91,17 +92,17 @@ abstract class AStoreable extends AExpression {
* Called before a storeable node is loaded or stored. Used to load prefixes and
* push load/store constants onto the stack if necessary.
*/
abstract void setup(MethodWriter writer, Globals globals);
abstract void setup(ClassWriter classWriter, MethodWriter writer, Globals globals);
/**
* Called to load a storable used for compound assignments.
*/
abstract void load(MethodWriter writer, Globals globals);
abstract void load(ClassWriter classWriter, MethodWriter writer, Globals globals);
/**
* Called to store a storabable to local memory.
*/
abstract void store(MethodWriter writer, Globals globals);
abstract void store(ClassWriter classWriter, MethodWriter writer, Globals globals);
/**
* Writes the opcodes to flip a negative array index (meaning slots from the end of the array) into a 0-based one (meaning slots from

View file

@ -21,6 +21,7 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -250,8 +251,8 @@ public final class EAssignment extends AExpression {
* also read from.
*/
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
// For the case where the assignment represents a String concatenation
// we must, depending on the Java version, write a StringBuilder or
@ -261,86 +262,87 @@ public final class EAssignment extends AExpression {
int catElementStackSize = 0;
if (cat) {
catElementStackSize = writer.writeNewStrings();
catElementStackSize = methodWriter.writeNewStrings();
}
// Cast the lhs to a storeable to perform the necessary operations to store the rhs.
AStoreable lhs = (AStoreable)this.lhs;
lhs.setup(writer, globals); // call the setup method on the lhs to prepare for a load/store operation
lhs.setup(classWriter, methodWriter, globals); // call the setup method on the lhs to prepare for a load/store operation
if (cat) {
// Handle the case where we are doing a compound assignment
// representing a String concatenation.
writer.writeDup(lhs.accessElementCount(), catElementStackSize); // dup the top element and insert it
methodWriter.writeDup(lhs.accessElementCount(), catElementStackSize); // dup the top element and insert it
// before concat helper on stack
lhs.load(writer, globals); // read the current lhs's value
writer.writeAppendStrings(lhs.actual); // append the lhs's value using the StringBuilder
lhs.load(classWriter, methodWriter, globals); // read the current lhs's value
methodWriter.writeAppendStrings(lhs.actual); // append the lhs's value using the StringBuilder
rhs.write(writer, globals); // write the bytecode for the rhs
rhs.write(classWriter, methodWriter, globals); // write the bytecode for the rhs
if (!(rhs instanceof EBinary) || !((EBinary)rhs).cat) { // check to see if the rhs has already done a concatenation
writer.writeAppendStrings(rhs.actual); // append the rhs's value since it's hasn't already
methodWriter.writeAppendStrings(rhs.actual); // append the rhs's value since it's hasn't already
}
writer.writeToStrings(); // put the value for string concat onto the stack
writer.writeCast(back); // if necessary, cast the String to the lhs actual type
methodWriter.writeToStrings(); // put the value for string concat onto the stack
methodWriter.writeCast(back); // if necessary, cast the String to the lhs actual type
if (lhs.read) {
writer.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // if this lhs is also read
methodWriter.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // if this lhs is also read
// from dup the value onto the stack
}
// store the lhs's value from the stack in its respective variable/field/array
lhs.store(writer, globals);
lhs.store(classWriter, methodWriter, globals); // store the lhs's value from the stack in its respective variable/field/array
} else if (operation != null) {
// Handle the case where we are doing a compound assignment that
// does not represent a String concatenation.
writer.writeDup(lhs.accessElementCount(), 0); // if necessary, dup the previous lhs's value
methodWriter.writeDup(lhs.accessElementCount(), 0); // if necessary, dup the previous lhs's value
// to be both loaded from and stored to
lhs.load(writer, globals); // load the current lhs's value
lhs.load(classWriter, methodWriter, globals); // load the current lhs's value
if (lhs.read && post) {
writer.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the lhs is also
// read from and is a post increment
methodWriter.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the
// lhs is also
// read from and is a post
// increment
}
writer.writeCast(there); // if necessary cast the current lhs's value
methodWriter.writeCast(there); // if necessary cast the current lhs's value
// to the promotion type between the lhs and rhs types
rhs.write(writer, globals); // write the bytecode for the rhs
rhs.write(classWriter, methodWriter, globals); // write the bytecode for the rhs
// XXX: fix these types, but first we need def compound assignment tests.
// its tricky here as there are possibly explicit casts, too.
// write the operation instruction for compound assignment
if (promote == def.class) {
writer.writeDynamicBinaryInstruction(
methodWriter.writeDynamicBinaryInstruction(
location, promote, def.class, def.class, operation, DefBootstrap.OPERATOR_COMPOUND_ASSIGNMENT);
} else {
writer.writeBinaryInstruction(location, promote, operation);
methodWriter.writeBinaryInstruction(location, promote, operation);
}
writer.writeCast(back); // if necessary cast the promotion type value back to the lhs's type
methodWriter.writeCast(back); // if necessary cast the promotion type value back to the lhs's type
if (lhs.read && !post) {
// dup the value if the lhs is also read from and is not a post increment
writer.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount());
methodWriter.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the lhs
// is also
// read from and is not a post
// increment
}
// store the lhs's value from the stack in its respective variable/field/array
lhs.store(writer, globals);
lhs.store(classWriter, methodWriter, globals); // store the lhs's value from the stack in its respective variable/field/array
} else {
// Handle the case for a simple write.
rhs.write(writer, globals); // write the bytecode for the rhs rhs
rhs.write(classWriter, methodWriter, globals); // write the bytecode for the rhs rhs
if (lhs.read) {
// dup the value if the lhs is also read from
writer.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount());
methodWriter.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the lhs
// is also read from
}
// store the lhs's value from the stack in its respective variable/field/array
lhs.store(writer, globals);
lhs.store(classWriter, methodWriter, globals); // store the lhs's value from the stack in its respective variable/field/array
}
}

View file

@ -20,6 +20,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -626,44 +627,44 @@ public final class EBinary extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (promote == String.class && operation == Operation.ADD) {
if (!cat) {
writer.writeNewStrings();
methodWriter.writeNewStrings();
}
left.write(writer, globals);
left.write(classWriter, methodWriter, globals);
if (!(left instanceof EBinary) || !((EBinary)left).cat) {
writer.writeAppendStrings(left.actual);
methodWriter.writeAppendStrings(left.actual);
}
right.write(writer, globals);
right.write(classWriter, methodWriter, globals);
if (!(right instanceof EBinary) || !((EBinary)right).cat) {
writer.writeAppendStrings(right.actual);
methodWriter.writeAppendStrings(right.actual);
}
if (!cat) {
writer.writeToStrings();
methodWriter.writeToStrings();
}
} else if (operation == Operation.FIND || operation == Operation.MATCH) {
right.write(writer, globals);
left.write(writer, globals);
writer.invokeVirtual(org.objectweb.asm.Type.getType(Pattern.class), WriterConstants.PATTERN_MATCHER);
right.write(classWriter, methodWriter, globals);
left.write(classWriter, methodWriter, globals);
methodWriter.invokeVirtual(org.objectweb.asm.Type.getType(Pattern.class), WriterConstants.PATTERN_MATCHER);
if (operation == Operation.FIND) {
writer.invokeVirtual(org.objectweb.asm.Type.getType(Matcher.class), WriterConstants.MATCHER_FIND);
methodWriter.invokeVirtual(org.objectweb.asm.Type.getType(Matcher.class), WriterConstants.MATCHER_FIND);
} else if (operation == Operation.MATCH) {
writer.invokeVirtual(org.objectweb.asm.Type.getType(Matcher.class), WriterConstants.MATCHER_MATCHES);
methodWriter.invokeVirtual(org.objectweb.asm.Type.getType(Matcher.class), WriterConstants.MATCHER_MATCHES);
} else {
throw new IllegalStateException("Illegal tree structure.");
}
} else {
left.write(writer, globals);
right.write(writer, globals);
left.write(classWriter, methodWriter, globals);
right.write(classWriter, methodWriter, globals);
if (promote == def.class || (shiftDistance != null && shiftDistance == def.class)) {
// def calls adopt the wanted return value. if there was a narrowing cast,
@ -672,9 +673,9 @@ public final class EBinary extends AExpression {
if (originallyExplicit) {
flags |= DefBootstrap.OPERATOR_EXPLICIT_CAST;
}
writer.writeDynamicBinaryInstruction(location, actual, left.actual, right.actual, operation, flags);
methodWriter.writeDynamicBinaryInstruction(location, actual, left.actual, right.actual, operation, flags);
} else {
writer.writeBinaryInstruction(location, actual, operation);
methodWriter.writeBinaryInstruction(location, actual, operation);
}
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -84,37 +85,37 @@ public final class EBool extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
if (operation == Operation.AND) {
Label fals = new Label();
Label end = new Label();
left.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, fals);
right.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, fals);
left.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
right.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
writer.push(true);
writer.goTo(end);
writer.mark(fals);
writer.push(false);
writer.mark(end);
methodWriter.push(true);
methodWriter.goTo(end);
methodWriter.mark(fals);
methodWriter.push(false);
methodWriter.mark(end);
} else if (operation == Operation.OR) {
Label tru = new Label();
Label fals = new Label();
Label end = new Label();
left.write(writer, globals);
writer.ifZCmp(Opcodes.IFNE, tru);
right.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, fals);
left.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFNE, tru);
right.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
writer.mark(tru);
writer.push(true);
writer.goTo(end);
writer.mark(fals);
writer.push(false);
writer.mark(end);
methodWriter.mark(tru);
methodWriter.push(true);
methodWriter.goTo(end);
methodWriter.mark(fals);
methodWriter.push(false);
methodWriter.mark(end);
} else {
throw createError(new IllegalStateException("Illegal tree structure."));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -58,7 +59,7 @@ public final class EBoolean extends AExpression {
}
@Override
void write(MethodWriter adapter, Globals globals) {
void write(ClassWriter classWriter, MethodWriter adapter, Globals globals) {
throw createError(new IllegalStateException("Illegal tree structure."));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -154,21 +155,21 @@ public final class ECallLocal extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (localMethod != null) {
for (AExpression argument : arguments) {
argument.write(writer, globals);
argument.write(classWriter, methodWriter, globals);
}
writer.invokeStatic(CLASS_TYPE, new Method(localMethod.name, localMethod.methodType.toMethodDescriptorString()));
methodWriter.invokeStatic(CLASS_TYPE, new Method(localMethod.name, localMethod.methodType.toMethodDescriptorString()));
} else if (importedMethod != null) {
for (AExpression argument : arguments) {
argument.write(writer, globals);
argument.write(classWriter, methodWriter, globals);
}
writer.invokeStatic(Type.getType(importedMethod.targetClass),
methodWriter.invokeStatic(Type.getType(importedMethod.targetClass),
new Method(importedMethod.javaMethod.getName(), importedMethod.methodType.toMethodDescriptorString()));
} else if (classBinding != null) {
String name = globals.addClassBinding(classBinding.javaConstructor.getDeclaringClass());
@ -177,45 +178,45 @@ public final class ECallLocal extends AExpression {
Label nonNull = new Label();
writer.loadThis();
writer.getField(CLASS_TYPE, name, type);
writer.ifNonNull(nonNull);
writer.loadThis();
writer.newInstance(type);
writer.dup();
methodWriter.loadThis();
methodWriter.getField(CLASS_TYPE, name, type);
methodWriter.ifNonNull(nonNull);
methodWriter.loadThis();
methodWriter.newInstance(type);
methodWriter.dup();
if (classBindingOffset == 1) {
writer.loadThis();
methodWriter.loadThis();
}
for (int argument = 0; argument < javaConstructorParameterCount; ++argument) {
arguments.get(argument).write(writer, globals);
arguments.get(argument).write(classWriter, methodWriter, globals);
}
writer.invokeConstructor(type, Method.getMethod(classBinding.javaConstructor));
writer.putField(CLASS_TYPE, name, type);
methodWriter.invokeConstructor(type, Method.getMethod(classBinding.javaConstructor));
methodWriter.putField(CLASS_TYPE, name, type);
writer.mark(nonNull);
writer.loadThis();
writer.getField(CLASS_TYPE, name, type);
methodWriter.mark(nonNull);
methodWriter.loadThis();
methodWriter.getField(CLASS_TYPE, name, type);
for (int argument = 0; argument < classBinding.javaMethod.getParameterCount(); ++argument) {
arguments.get(argument + javaConstructorParameterCount).write(writer, globals);
arguments.get(argument + javaConstructorParameterCount).write(classWriter, methodWriter, globals);
}
writer.invokeVirtual(type, Method.getMethod(classBinding.javaMethod));
methodWriter.invokeVirtual(type, Method.getMethod(classBinding.javaMethod));
} else if (instanceBinding != null) {
String name = globals.addInstanceBinding(instanceBinding.targetInstance);
Type type = Type.getType(instanceBinding.targetInstance.getClass());
writer.loadThis();
writer.getStatic(CLASS_TYPE, name, type);
methodWriter.loadThis();
methodWriter.getStatic(CLASS_TYPE, name, type);
for (int argument = 0; argument < instanceBinding.javaMethod.getParameterCount(); ++argument) {
arguments.get(argument).write(writer, globals);
arguments.get(argument).write(classWriter, methodWriter, globals);
}
writer.invokeVirtual(type, Method.getMethod(instanceBinding.javaMethod));
methodWriter.invokeVirtual(type, Method.getMethod(instanceBinding.javaMethod));
} else {
throw new IllegalStateException("Illegal tree structure.");
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.FunctionRef;
@ -87,22 +88,22 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (defPointer != null) {
// dynamic interface: push captured parameter on stack
// TODO: don't do this: its just to cutover :)
writer.push((String)null);
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
methodWriter.push((String)null);
methodWriter.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
} else if (ref == null) {
// typed interface, dynamic implementation
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
Type methodType = Type.getMethodType(MethodWriter.getType(expected), MethodWriter.getType(captured.clazz));
writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.typeToCanonicalTypeName(expected));
methodWriter.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.typeToCanonicalTypeName(expected));
} else {
// typed interface, typed implementation
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
writer.invokeLambdaCall(ref);
methodWriter.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
methodWriter.invokeLambdaCall(ref);
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -61,10 +62,10 @@ final class ECast extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
child.write(writer, globals);
writer.writeDebugInfo(location);
writer.writeCast(cast);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
child.write(classWriter, methodWriter, globals);
methodWriter.writeDebugInfo(location);
methodWriter.writeCast(cast);
}
@Override

View file

@ -20,6 +20,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -435,13 +436,13 @@ public final class EComp extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
left.write(writer, globals);
left.write(classWriter, methodWriter, globals);
if (!right.isNull) {
right.write(writer, globals);
right.write(classWriter, methodWriter, globals);
}
Label jump = new Label();
@ -461,18 +462,18 @@ public final class EComp extends AExpression {
if (promotedType == void.class || promotedType == byte.class || promotedType == short.class || promotedType == char.class) {
throw createError(new IllegalStateException("Illegal tree structure."));
} else if (promotedType == boolean.class) {
if (eq) writer.ifCmp(type, MethodWriter.EQ, jump);
else if (ne) writer.ifCmp(type, MethodWriter.NE, jump);
if (eq) methodWriter.ifCmp(type, MethodWriter.EQ, jump);
else if (ne) methodWriter.ifCmp(type, MethodWriter.NE, jump);
else {
throw createError(new IllegalStateException("Illegal tree structure."));
}
} else if (promotedType == int.class || promotedType == long.class || promotedType == float.class || promotedType == double.class) {
if (eq) writer.ifCmp(type, MethodWriter.EQ, jump);
else if (ne) writer.ifCmp(type, MethodWriter.NE, jump);
else if (lt) writer.ifCmp(type, MethodWriter.LT, jump);
else if (lte) writer.ifCmp(type, MethodWriter.LE, jump);
else if (gt) writer.ifCmp(type, MethodWriter.GT, jump);
else if (gte) writer.ifCmp(type, MethodWriter.GE, jump);
if (eq) methodWriter.ifCmp(type, MethodWriter.EQ, jump);
else if (ne) methodWriter.ifCmp(type, MethodWriter.NE, jump);
else if (lt) methodWriter.ifCmp(type, MethodWriter.LT, jump);
else if (lte) methodWriter.ifCmp(type, MethodWriter.LE, jump);
else if (gt) methodWriter.ifCmp(type, MethodWriter.GT, jump);
else if (gte) methodWriter.ifCmp(type, MethodWriter.GE, jump);
else {
throw createError(new IllegalStateException("Illegal tree structure."));
}
@ -483,33 +484,33 @@ public final class EComp extends AExpression {
if (eq) {
if (right.isNull) {
writer.ifNull(jump);
methodWriter.ifNull(jump);
} else if (!left.isNull && operation == Operation.EQ) {
writer.invokeDefCall("eq", descriptor, DefBootstrap.BINARY_OPERATOR, DefBootstrap.OPERATOR_ALLOWS_NULL);
methodWriter.invokeDefCall("eq", descriptor, DefBootstrap.BINARY_OPERATOR, DefBootstrap.OPERATOR_ALLOWS_NULL);
writejump = false;
} else {
writer.ifCmp(type, MethodWriter.EQ, jump);
methodWriter.ifCmp(type, MethodWriter.EQ, jump);
}
} else if (ne) {
if (right.isNull) {
writer.ifNonNull(jump);
methodWriter.ifNonNull(jump);
} else if (!left.isNull && operation == Operation.NE) {
writer.invokeDefCall("eq", descriptor, DefBootstrap.BINARY_OPERATOR, DefBootstrap.OPERATOR_ALLOWS_NULL);
writer.ifZCmp(MethodWriter.EQ, jump);
methodWriter.invokeDefCall("eq", descriptor, DefBootstrap.BINARY_OPERATOR, DefBootstrap.OPERATOR_ALLOWS_NULL);
methodWriter.ifZCmp(MethodWriter.EQ, jump);
} else {
writer.ifCmp(type, MethodWriter.NE, jump);
methodWriter.ifCmp(type, MethodWriter.NE, jump);
}
} else if (lt) {
writer.invokeDefCall("lt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
methodWriter.invokeDefCall("lt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
writejump = false;
} else if (lte) {
writer.invokeDefCall("lte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
methodWriter.invokeDefCall("lte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
writejump = false;
} else if (gt) {
writer.invokeDefCall("gt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
methodWriter.invokeDefCall("gt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
writejump = false;
} else if (gte) {
writer.invokeDefCall("gte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
methodWriter.invokeDefCall("gte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
writejump = false;
} else {
throw createError(new IllegalStateException("Illegal tree structure."));
@ -517,21 +518,21 @@ public final class EComp extends AExpression {
} else {
if (eq) {
if (right.isNull) {
writer.ifNull(jump);
methodWriter.ifNull(jump);
} else if (operation == Operation.EQ) {
writer.invokeStatic(OBJECTS_TYPE, EQUALS);
methodWriter.invokeStatic(OBJECTS_TYPE, EQUALS);
writejump = false;
} else {
writer.ifCmp(type, MethodWriter.EQ, jump);
methodWriter.ifCmp(type, MethodWriter.EQ, jump);
}
} else if (ne) {
if (right.isNull) {
writer.ifNonNull(jump);
methodWriter.ifNonNull(jump);
} else if (operation == Operation.NE) {
writer.invokeStatic(OBJECTS_TYPE, EQUALS);
writer.ifZCmp(MethodWriter.EQ, jump);
methodWriter.invokeStatic(OBJECTS_TYPE, EQUALS);
methodWriter.ifZCmp(MethodWriter.EQ, jump);
} else {
writer.ifCmp(type, MethodWriter.NE, jump);
methodWriter.ifCmp(type, MethodWriter.NE, jump);
}
} else {
throw createError(new IllegalStateException("Illegal tree structure."));
@ -539,11 +540,11 @@ public final class EComp extends AExpression {
}
if (writejump) {
writer.push(false);
writer.goTo(end);
writer.mark(jump);
writer.push(true);
writer.mark(end);
methodWriter.push(false);
methodWriter.goTo(end);
methodWriter.mark(jump);
methodWriter.push(true);
methodWriter.mark(end);
}
}

View file

@ -20,6 +20,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -96,20 +97,20 @@ public final class EConditional extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
Label fals = new Label();
Label end = new Label();
condition.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, fals);
condition.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
left.write(writer, globals);
writer.goTo(end);
writer.mark(fals);
right.write(writer, globals);
writer.mark(end);
left.write(classWriter, methodWriter, globals);
methodWriter.goTo(end);
methodWriter.mark(fals);
right.write(classWriter, methodWriter, globals);
methodWriter.mark(end);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -75,16 +76,16 @@ final class EConstant extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
if (actual == String.class) writer.push((String)constant);
else if (actual == double.class) writer.push((double)constant);
else if (actual == float.class) writer.push((float)constant);
else if (actual == long.class) writer.push((long)constant);
else if (actual == int.class) writer.push((int)constant);
else if (actual == char.class) writer.push((char)constant);
else if (actual == short.class) writer.push((short)constant);
else if (actual == byte.class) writer.push((byte)constant);
else if (actual == boolean.class) writer.push((boolean)constant);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
if (actual == String.class) methodWriter.push((String)constant);
else if (actual == double.class) methodWriter.push((double)constant);
else if (actual == float.class) methodWriter.push((float)constant);
else if (actual == long.class) methodWriter.push((long)constant);
else if (actual == int.class) methodWriter.push((int)constant);
else if (actual == char.class) methodWriter.push((char)constant);
else if (actual == short.class) methodWriter.push((short)constant);
else if (actual == byte.class) methodWriter.push((byte)constant);
else if (actual == boolean.class) methodWriter.push((boolean)constant);
else {
throw createError(new IllegalStateException("Illegal tree structure."));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -79,7 +80,7 @@ public final class EDecimal extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw createError(new IllegalStateException("Illegal tree structure."));
}

View file

@ -20,6 +20,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -99,17 +100,17 @@ public class EElvis extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
Label end = new Label();
lhs.write(writer, globals);
writer.dup();
writer.ifNonNull(end);
writer.pop();
rhs.write(writer, globals);
writer.mark(end);
lhs.write(classWriter, methodWriter, globals);
methodWriter.dup();
methodWriter.ifNonNull(end);
methodWriter.pop();
rhs.write(classWriter, methodWriter, globals);
methodWriter.mark(end);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -68,7 +69,7 @@ public final class EExplicit extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw createError(new IllegalStateException("Illegal tree structure."));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.FunctionRef;
import org.elasticsearch.painless.Globals;
@ -71,13 +72,13 @@ public final class EFunctionRef extends AExpression implements ILambda {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
if (ref != null) {
writer.writeDebugInfo(location);
writer.invokeLambdaCall(ref);
methodWriter.writeDebugInfo(location);
methodWriter.invokeLambdaCall(ref);
} else {
// TODO: don't do this: its just to cutover :)
writer.push((String)null);
methodWriter.push((String)null);
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -87,19 +88,19 @@ public final class EInstanceof extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
// primitive types
if (primitiveExpression) {
// run the expression anyway (who knows what it does)
expression.write(writer, globals);
expression.write(classWriter, methodWriter, globals);
// discard its result
writer.writePop(MethodWriter.getType(expression.actual).getSize());
methodWriter.writePop(MethodWriter.getType(expression.actual).getSize());
// push our result: its a primitive so it cannot be null.
writer.push(resolvedType.isAssignableFrom(expressionType));
methodWriter.push(resolvedType.isAssignableFrom(expressionType));
} else {
// ordinary instanceof
expression.write(writer, globals);
writer.instanceOf(org.objectweb.asm.Type.getType(resolvedType));
expression.write(classWriter, methodWriter, globals);
methodWriter.instanceOf(org.objectweb.asm.Type.getType(resolvedType));
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.FunctionRef;
import org.elasticsearch.painless.Globals;
@ -196,23 +197,23 @@ public final class ELambda extends AExpression implements ILambda {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (ref != null) {
writer.writeDebugInfo(location);
methodWriter.writeDebugInfo(location);
// load captures
for (Variable capture : captures) {
writer.visitVarInsn(MethodWriter.getType(capture.clazz).getOpcode(Opcodes.ILOAD), capture.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(capture.clazz).getOpcode(Opcodes.ILOAD), capture.getSlot());
}
writer.invokeLambdaCall(ref);
methodWriter.invokeLambdaCall(ref);
} else {
// placeholder
writer.push((String)null);
methodWriter.push((String)null);
// load captures
for (Variable capture : captures) {
writer.visitVarInsn(MethodWriter.getType(capture.clazz).getOpcode(Opcodes.ILOAD), capture.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(capture.clazz).getOpcode(Opcodes.ILOAD), capture.getSlot());
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -97,19 +98,19 @@ public final class EListInit extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
writer.newInstance(MethodWriter.getType(actual));
writer.dup();
writer.invokeConstructor(
methodWriter.newInstance(MethodWriter.getType(actual));
methodWriter.dup();
methodWriter.invokeConstructor(
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
for (AExpression value : values) {
writer.dup();
value.write(writer, globals);
writer.invokeMethodCall(method);
writer.pop();
methodWriter.dup();
value.write(classWriter, methodWriter, globals);
methodWriter.invokeMethodCall(method);
methodWriter.pop();
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -120,23 +121,23 @@ public final class EMapInit extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
writer.newInstance(MethodWriter.getType(actual));
writer.dup();
writer.invokeConstructor(
methodWriter.newInstance(MethodWriter.getType(actual));
methodWriter.dup();
methodWriter.invokeConstructor(
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
for (int index = 0; index < keys.size(); ++index) {
AExpression key = keys.get(index);
AExpression value = values.get(index);
writer.dup();
key.write(writer, globals);
value.write(writer, globals);
writer.invokeMethodCall(method);
writer.pop();
methodWriter.dup();
key.write(classWriter, methodWriter, globals);
value.write(classWriter, methodWriter, globals);
methodWriter.invokeMethodCall(method);
methodWriter.pop();
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -85,30 +86,30 @@ public final class ENewArray extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (initialize) {
writer.push(arguments.size());
writer.newArray(MethodWriter.getType(actual.getComponentType()));
methodWriter.push(arguments.size());
methodWriter.newArray(MethodWriter.getType(actual.getComponentType()));
for (int index = 0; index < arguments.size(); ++index) {
AExpression argument = arguments.get(index);
writer.dup();
writer.push(index);
argument.write(writer, globals);
writer.arrayStore(MethodWriter.getType(actual.getComponentType()));
methodWriter.dup();
methodWriter.push(index);
argument.write(classWriter, methodWriter, globals);
methodWriter.arrayStore(MethodWriter.getType(actual.getComponentType()));
}
} else {
for (AExpression argument : arguments) {
argument.write(writer, globals);
argument.write(classWriter, methodWriter, globals);
}
if (arguments.size() > 1) {
writer.visitMultiANewArrayInsn(MethodWriter.getType(actual).getDescriptor(), arguments.size());
methodWriter.visitMultiANewArrayInsn(MethodWriter.getType(actual).getDescriptor(), arguments.size());
} else {
writer.newArray(MethodWriter.getType(actual.getComponentType()));
methodWriter.newArray(MethodWriter.getType(actual.getComponentType()));
}
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.FunctionRef;
import org.elasticsearch.painless.Globals;
@ -85,13 +86,13 @@ public final class ENewArrayFunctionRef extends AExpression implements ILambda {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
if (ref != null) {
writer.writeDebugInfo(location);
writer.invokeLambdaCall(ref);
methodWriter.writeDebugInfo(location);
methodWriter.invokeLambdaCall(ref);
} else {
// push a null instruction as a placeholder for future lambda instructions
writer.push((String)null);
methodWriter.push((String)null);
}
globals.addSyntheticMethod(function);

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -103,20 +104,20 @@ public final class ENewObj extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
writer.newInstance(MethodWriter.getType(actual));
methodWriter.newInstance(MethodWriter.getType(actual));
if (read) {
writer.dup();
methodWriter.dup();
}
for (AExpression argument : arguments) {
argument.write(writer, globals);
argument.write(classWriter, methodWriter, globals);
}
writer.invokeConstructor(
methodWriter.invokeConstructor(
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -69,8 +70,8 @@ public final class ENull extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.visitInsn(Opcodes.ACONST_NULL);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.visitInsn(Opcodes.ACONST_NULL);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -121,7 +122,7 @@ public final class ENumeric extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw createError(new IllegalStateException("Illegal tree structure."));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Constant;
import org.elasticsearch.painless.Globals;
@ -91,10 +92,10 @@ public final class ERegex extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
writer.getStatic(WriterConstants.CLASS_TYPE, constant.name, org.objectweb.asm.Type.getType(Pattern.class));
methodWriter.getStatic(WriterConstants.CLASS_TYPE, constant.name, org.objectweb.asm.Type.getType(Pattern.class));
globals.addConstantInitializer(constant);
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -61,7 +62,7 @@ public final class EStatic extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
// Do nothing.
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -59,7 +60,7 @@ public final class EString extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw new IllegalStateException("Illegal tree structure.");
}

View file

@ -20,6 +20,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -192,23 +193,23 @@ public final class EUnary extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (operation == Operation.NOT) {
Label fals = new Label();
Label end = new Label();
child.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, fals);
child.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
writer.push(false);
writer.goTo(end);
writer.mark(fals);
writer.push(true);
writer.mark(end);
methodWriter.push(false);
methodWriter.goTo(end);
methodWriter.mark(fals);
methodWriter.push(true);
methodWriter.mark(end);
} else {
child.write(writer, globals);
child.write(classWriter, methodWriter, globals);
// Def calls adopt the wanted return value. If there was a narrowing cast,
// we need to flag that so that it's done at runtime.
@ -224,29 +225,29 @@ public final class EUnary extends AExpression {
if (operation == Operation.BWNOT) {
if (promote == def.class) {
org.objectweb.asm.Type descriptor = org.objectweb.asm.Type.getMethodType(actualType, childType);
writer.invokeDefCall("not", descriptor, DefBootstrap.UNARY_OPERATOR, defFlags);
methodWriter.invokeDefCall("not", descriptor, DefBootstrap.UNARY_OPERATOR, defFlags);
} else {
if (promote == int.class) {
writer.push(-1);
methodWriter.push(-1);
} else if (promote == long.class) {
writer.push(-1L);
methodWriter.push(-1L);
} else {
throw createError(new IllegalStateException("Illegal tree structure."));
}
writer.math(MethodWriter.XOR, actualType);
methodWriter.math(MethodWriter.XOR, actualType);
}
} else if (operation == Operation.SUB) {
if (promote == def.class) {
org.objectweb.asm.Type descriptor = org.objectweb.asm.Type.getMethodType(actualType, childType);
writer.invokeDefCall("neg", descriptor, DefBootstrap.UNARY_OPERATOR, defFlags);
methodWriter.invokeDefCall("neg", descriptor, DefBootstrap.UNARY_OPERATOR, defFlags);
} else {
writer.math(MethodWriter.NEG, actualType);
methodWriter.math(MethodWriter.NEG, actualType);
}
} else if (operation == Operation.ADD) {
if (promote == def.class) {
org.objectweb.asm.Type descriptor = org.objectweb.asm.Type.getMethodType(actualType, childType);
writer.invokeDefCall("plus", descriptor, DefBootstrap.UNARY_OPERATOR, defFlags);
methodWriter.invokeDefCall("plus", descriptor, DefBootstrap.UNARY_OPERATOR, defFlags);
}
} else {
throw createError(new IllegalStateException("Illegal tree structure."));

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -67,8 +68,8 @@ public final class EVariable extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
}
@Override
@ -87,18 +88,18 @@ public final class EVariable extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
// Do nothing.
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ISTORE), variable.getSlot());
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ISTORE), variable.getSlot());
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -87,9 +88,9 @@ public final class PBrace extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
prefix.write(writer, globals);
sub.write(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
prefix.write(classWriter, methodWriter, globals);
sub.write(classWriter, methodWriter, globals);
}
@Override
@ -109,19 +110,19 @@ public final class PBrace extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
prefix.write(writer, globals);
sub.setup(writer, globals);
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
prefix.write(classWriter, methodWriter, globals);
sub.setup(classWriter, methodWriter, globals);
}
@Override
void load(MethodWriter writer, Globals globals) {
sub.load(writer, globals);
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
sub.load(classWriter, methodWriter, globals);
}
@Override
void store(MethodWriter writer, Globals globals) {
sub.store(writer, globals);
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
sub.store(classWriter, methodWriter, globals);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -103,9 +104,9 @@ public final class PCallInvoke extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
prefix.write(writer, globals);
sub.write(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
prefix.write(classWriter, methodWriter, globals);
sub.write(classWriter, methodWriter, globals);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -128,9 +129,9 @@ public final class PField extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
prefix.write(writer, globals);
sub.write(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
prefix.write(classWriter, methodWriter, globals);
sub.write(classWriter, methodWriter, globals);
}
@Override
@ -150,19 +151,19 @@ public final class PField extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
prefix.write(writer, globals);
sub.setup(writer, globals);
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
prefix.write(classWriter, methodWriter, globals);
sub.setup(classWriter, methodWriter, globals);
}
@Override
void load(MethodWriter writer, Globals globals) {
sub.load(writer, globals);
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
sub.load(classWriter, methodWriter, globals);
}
@Override
void store(MethodWriter writer, Globals globals) {
sub.store(writer, globals);
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
sub.store(classWriter, methodWriter, globals);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -67,9 +68,9 @@ final class PSubArrayLength extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
writer.arrayLength();
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
methodWriter.arrayLength();
}
@Override
@ -88,17 +89,17 @@ final class PSubArrayLength extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw new IllegalStateException("Illegal tree structure.");
}
@Override
void load(MethodWriter writer, Globals globals) {
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw new IllegalStateException("Illegal tree structure.");
}
@Override
void store(MethodWriter writer, Globals globals) {
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw new IllegalStateException("Illegal tree structure.");
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -63,9 +64,9 @@ final class PSubBrace extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
setup(writer, globals);
load(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
setup(classWriter, methodWriter, globals);
load(classWriter, methodWriter, globals);
}
@Override
@ -84,21 +85,21 @@ final class PSubBrace extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
index.write(writer, globals);
writeIndexFlip(writer, MethodWriter::arrayLength);
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
index.write(classWriter, methodWriter, globals);
writeIndexFlip(methodWriter, MethodWriter::arrayLength);
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
writer.arrayLoad(MethodWriter.getType(actual));
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
methodWriter.arrayLoad(MethodWriter.getType(actual));
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
writer.arrayStore(MethodWriter.getType(actual));
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
methodWriter.arrayStore(MethodWriter.getType(actual));
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -73,18 +74,18 @@ final class PSubCallInvoke extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (box.isPrimitive()) {
writer.box(MethodWriter.getType(box));
methodWriter.box(MethodWriter.getType(box));
}
for (AExpression argument : arguments) {
argument.write(writer, globals);
argument.write(classWriter, methodWriter, globals);
}
writer.invokeMethodCall(method);
methodWriter.invokeMethodCall(method);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -65,9 +66,9 @@ final class PSubDefArray extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
setup(writer, globals);
load(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
setup(classWriter, methodWriter, globals);
load(classWriter, methodWriter, globals);
}
@Override
@ -86,32 +87,31 @@ final class PSubDefArray extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
// Current stack: def
writer.dup(); // def, def
index.write(writer, globals); // def, def, unnormalized_index
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.dup();
index.write(classWriter, methodWriter, globals);
Type methodType = Type.getMethodType(
MethodWriter.getType(index.actual), Type.getType(Object.class), MethodWriter.getType(index.actual));
writer.invokeDefCall("normalizeIndex", methodType, DefBootstrap.INDEX_NORMALIZE); // def, normalized_index
methodWriter.invokeDefCall("normalizeIndex", methodType, DefBootstrap.INDEX_NORMALIZE);
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
Type methodType =
Type.getMethodType(MethodWriter.getType(actual), Type.getType(Object.class), MethodWriter.getType(index.actual));
writer.invokeDefCall("arrayLoad", methodType, DefBootstrap.ARRAY_LOAD);
methodWriter.invokeDefCall("arrayLoad", methodType, DefBootstrap.ARRAY_LOAD);
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
Type methodType =
Type.getMethodType(
Type.getType(void.class), Type.getType(Object.class), MethodWriter.getType(index.actual), MethodWriter.getType(actual));
writer.invokeDefCall("arrayStore", methodType, DefBootstrap.ARRAY_STORE);
methodWriter.invokeDefCall("arrayStore", methodType, DefBootstrap.ARRAY_STORE);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -96,8 +97,8 @@ final class PSubDefCall extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
List<Type> parameterTypes = new ArrayList<>();
@ -113,7 +114,7 @@ final class PSubDefCall extends AExpression {
Collections.addAll(parameterTypes, lambda.getCaptures());
}
argument.write(writer, globals);
argument.write(classWriter, methodWriter, globals);
}
// create method type from return value and arguments
@ -122,7 +123,7 @@ final class PSubDefCall extends AExpression {
List<Object> args = new ArrayList<>();
args.add(recipe.toString());
args.addAll(pointers);
writer.invokeDefCall(name, methodType, DefBootstrap.METHOD_CALL, args.toArray());
methodWriter.invokeDefCall(name, methodType, DefBootstrap.METHOD_CALL, args.toArray());
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -61,12 +62,12 @@ final class PSubDefField extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
org.objectweb.asm.Type methodType =
org.objectweb.asm.Type.getMethodType(MethodWriter.getType(actual), org.objectweb.asm.Type.getType(Object.class));
writer.invokeDefCall(value, methodType, DefBootstrap.LOAD);
methodWriter.invokeDefCall(value, methodType, DefBootstrap.LOAD);
}
@Override
@ -85,26 +86,26 @@ final class PSubDefField extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
// Do nothing.
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
org.objectweb.asm.Type methodType =
org.objectweb.asm.Type.getMethodType(MethodWriter.getType(actual), org.objectweb.asm.Type.getType(Object.class));
writer.invokeDefCall(value, methodType, DefBootstrap.LOAD);
methodWriter.invokeDefCall(value, methodType, DefBootstrap.LOAD);
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
org.objectweb.asm.Type methodType = org.objectweb.asm.Type.getMethodType(
org.objectweb.asm.Type.getType(void.class), org.objectweb.asm.Type.getType(Object.class), MethodWriter.getType(actual));
writer.invokeDefCall(value, methodType, DefBootstrap.STORE);
methodWriter.invokeDefCall(value, methodType, DefBootstrap.STORE);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -66,14 +67,14 @@ final class PSubField extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
if (java.lang.reflect.Modifier.isStatic(field.javaField.getModifiers())) {
writer.getStatic(Type.getType(
methodWriter.getStatic(Type.getType(
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
} else {
writer.getField(Type.getType(
methodWriter.getField(Type.getType(
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
}
}
@ -94,32 +95,32 @@ final class PSubField extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
void setup(ClassWriter classWriter, MethodWriter methodWriter,Globals globals) {
// Do nothing.
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void load(ClassWriter classWriter, MethodWriter methodWriter,Globals globals) {
methodWriter.writeDebugInfo(location);
if (java.lang.reflect.Modifier.isStatic(field.javaField.getModifiers())) {
writer.getStatic(Type.getType(
methodWriter.getStatic(Type.getType(
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
} else {
writer.getField(Type.getType(
methodWriter.getField(Type.getType(
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
}
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void store(ClassWriter classWriter, MethodWriter methodWriter,Globals globals) {
methodWriter.writeDebugInfo(location);
if (java.lang.reflect.Modifier.isStatic(field.javaField.getModifiers())) {
writer.putStatic(Type.getType(
methodWriter.putStatic(Type.getType(
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
} else {
writer.putField(Type.getType(
methodWriter.putField(Type.getType(
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -92,9 +93,9 @@ final class PSubListShortcut extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
setup(writer, globals);
load(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
setup(classWriter, methodWriter, globals);
load(classWriter, methodWriter, globals);
}
@Override
@ -113,28 +114,28 @@ final class PSubListShortcut extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
index.write(writer, globals);
writeIndexFlip(writer, w -> {
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
index.write(classWriter, methodWriter, globals);
writeIndexFlip(methodWriter, w -> {
w.invokeInterface(WriterConstants.COLLECTION_TYPE, WriterConstants.COLLECTION_SIZE);
});
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
writer.invokeMethodCall(getter);
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
methodWriter.invokeMethodCall(getter);
if (getter.returnType == getter.javaMethod.getReturnType()) {
writer.checkCast(MethodWriter.getType(getter.returnType));
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
}
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
writer.invokeMethodCall(setter);
writer.writePop(MethodWriter.getType(setter.returnType).getSize());
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
methodWriter.invokeMethodCall(setter);
methodWriter.writePop(MethodWriter.getType(setter.returnType).getSize());
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -90,14 +91,14 @@ final class PSubMapShortcut extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
index.write(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
index.write(classWriter, methodWriter, globals);
writer.writeDebugInfo(location);
writer.invokeMethodCall(getter);
methodWriter.writeDebugInfo(location);
methodWriter.invokeMethodCall(getter);
if (getter.returnType != getter.javaMethod.getReturnType()) {
writer.checkCast(MethodWriter.getType(getter.returnType));
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
}
}
@ -117,25 +118,25 @@ final class PSubMapShortcut extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
index.write(writer, globals);
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
index.write(classWriter, methodWriter, globals);
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
writer.invokeMethodCall(getter);
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
methodWriter.invokeMethodCall(getter);
if (getter.returnType != getter.javaMethod.getReturnType()) {
writer.checkCast(MethodWriter.getType(getter.returnType));
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
}
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
writer.invokeMethodCall(setter);
writer.writePop(MethodWriter.getType(setter.returnType).getSize());
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
methodWriter.invokeMethodCall(setter);
methodWriter.writePop(MethodWriter.getType(setter.returnType).getSize());
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -64,14 +65,14 @@ public class PSubNullSafeCallInvoke extends AExpression {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
Label end = new Label();
writer.dup();
writer.ifNull(end);
guarded.write(writer, globals);
writer.mark(end);
methodWriter.dup();
methodWriter.ifNull(end);
guarded.write(classWriter, methodWriter, globals);
methodWriter.mark(end);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -79,26 +80,26 @@ public class PSubNullSafeField extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
Label end = new Label();
writer.dup();
writer.ifNull(end);
guarded.write(writer, globals);
writer.mark(end);
methodWriter.dup();
methodWriter.ifNull(end);
guarded.write(classWriter, methodWriter, globals);
methodWriter.mark(end);
}
@Override
void setup(MethodWriter writer, Globals globals) {
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw createError(new IllegalArgumentException("Can't write to null safe field"));
}
@Override
void load(MethodWriter writer, Globals globals) {
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw createError(new IllegalArgumentException("Can't write to null safe field"));
}
@Override
void store(MethodWriter writer, Globals globals) {
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
throw createError(new IllegalArgumentException("Can't write to null safe field"));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -81,13 +82,13 @@ final class PSubShortcut extends AStoreable {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
writer.invokeMethodCall(getter);
methodWriter.invokeMethodCall(getter);
if (!getter.returnType.equals(getter.javaMethod.getReturnType())) {
writer.checkCast(MethodWriter.getType(getter.returnType));
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
}
}
@ -107,28 +108,28 @@ final class PSubShortcut extends AStoreable {
}
@Override
void setup(MethodWriter writer, Globals globals) {
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
// Do nothing.
}
@Override
void load(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
writer.invokeMethodCall(getter);
methodWriter.invokeMethodCall(getter);
if (getter.returnType != getter.javaMethod.getReturnType()) {
writer.checkCast(MethodWriter.getType(getter.returnType));
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
}
}
@Override
void store(MethodWriter writer, Globals globals) {
writer.writeDebugInfo(location);
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeDebugInfo(location);
writer.invokeMethodCall(setter);
methodWriter.invokeMethodCall(setter);
writer.writePop(MethodWriter.getType(setter.returnType).getSize());
methodWriter.writePop(MethodWriter.getType(setter.returnType).getSize());
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -89,11 +90,11 @@ public final class SBlock extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
for (AStatement statement : statements) {
statement.continu = continu;
statement.brake = brake;
statement.write(writer, globals);
statement.write(classWriter, methodWriter, globals);
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -59,8 +60,8 @@ public final class SBreak extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.goTo(brake);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.goTo(brake);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -101,24 +102,24 @@ public final class SCatch extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
Label jump = new Label();
writer.mark(jump);
writer.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
methodWriter.mark(jump);
methodWriter.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
if (block != null) {
block.continu = continu;
block.brake = brake;
block.write(writer, globals);
block.write(classWriter, methodWriter, globals);
}
writer.visitTryCatchBlock(begin, end, jump, MethodWriter.getType(variable.clazz).getInternalName());
methodWriter.visitTryCatchBlock(begin, end, jump, MethodWriter.getType(variable.clazz).getInternalName());
if (exception != null && (block == null || !block.allEscape)) {
writer.goTo(exception);
methodWriter.goTo(exception);
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Constant;
import org.elasticsearch.painless.Globals;
@ -28,16 +29,13 @@ import org.elasticsearch.painless.Locals.Variable;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.ScriptClassInfo;
import org.elasticsearch.painless.SimpleChecksAdapter;
import org.elasticsearch.painless.WriterConstants;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.TraceClassVisitor;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
@ -199,30 +197,19 @@ public final class SClass extends AStatement {
public Map<String, Object> write() {
// Create the ClassWriter.
int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS;
int classFrames = org.objectweb.asm.ClassWriter.COMPUTE_FRAMES | org.objectweb.asm.ClassWriter.COMPUTE_MAXS;
int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL;
String interfaceBase = BASE_INTERFACE_TYPE.getInternalName();
String className = CLASS_TYPE.getInternalName();
String classInterfaces[] = new String[] { interfaceBase };
String[] classInterfaces = new String[] { interfaceBase };
ClassWriter writer = new ClassWriter(classFrames);
ClassVisitor visitor = writer;
// if picky is enabled, turn on some checks. instead of VerifyError at the end, you get a helpful stacktrace.
if (settings.isPicky()) {
visitor = new SimpleChecksAdapter(visitor);
}
if (debugStream != null) {
visitor = new TraceClassVisitor(visitor, debugStream, null);
}
visitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null,
Type.getType(scriptClassInfo.getBaseClass()).getInternalName(), classInterfaces);
visitor.visitSource(Location.computeSourceName(name), null);
ClassWriter classWriter = new ClassWriter(settings, globals.getStatements(), debugStream,
scriptClassInfo.getBaseClass(), classFrames, classAccess, className, classInterfaces);
ClassVisitor classVisitor = classWriter.getClassVisitor();
classVisitor.visitSource(Location.computeSourceName(name), null);
// Write the a method to bootstrap def calls
MethodWriter bootstrapDef = new MethodWriter(Opcodes.ACC_STATIC | Opcodes.ACC_VARARGS, DEF_BOOTSTRAP_METHOD, visitor,
globals.getStatements(), settings);
MethodWriter bootstrapDef = classWriter.newMethodWriter(Opcodes.ACC_STATIC | Opcodes.ACC_VARARGS, DEF_BOOTSTRAP_METHOD);
bootstrapDef.visitCode();
bootstrapDef.getStatic(CLASS_TYPE, "$DEFINITION", DEFINITION_TYPE);
bootstrapDef.getStatic(CLASS_TYPE, "$LOCALS", MAP_TYPE);
@ -232,13 +219,14 @@ public final class SClass extends AStatement {
bootstrapDef.endMethod();
// Write static variables for name, source and statements used for writing exception messages
visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$NAME", STRING_TYPE.getDescriptor(), null, null).visitEnd();
visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$SOURCE", STRING_TYPE.getDescriptor(), null, null).visitEnd();
visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$STATEMENTS", BITSET_TYPE.getDescriptor(), null, null).visitEnd();
classVisitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$NAME", STRING_TYPE.getDescriptor(), null, null).visitEnd();
classVisitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$SOURCE", STRING_TYPE.getDescriptor(), null, null).visitEnd();
classVisitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$STATEMENTS", BITSET_TYPE.getDescriptor(), null, null).visitEnd();
// Write the static variables used by the method to bootstrap def calls
visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$DEFINITION", DEFINITION_TYPE.getDescriptor(), null, null).visitEnd();
visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$LOCALS", MAP_TYPE.getDescriptor(), null, null).visitEnd();
classVisitor.visitField(
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$DEFINITION", DEFINITION_TYPE.getDescriptor(), null, null).visitEnd();
classVisitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$LOCALS", MAP_TYPE.getDescriptor(), null, null).visitEnd();
org.objectweb.asm.commons.Method init;
@ -250,7 +238,7 @@ public final class SClass extends AStatement {
}
// Write the constructor:
MethodWriter constructor = new MethodWriter(Opcodes.ACC_PUBLIC, init, visitor, globals.getStatements(), settings);
MethodWriter constructor = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, init);
constructor.visitCode();
constructor.loadThis();
constructor.loadArgs();
@ -259,37 +247,35 @@ public final class SClass extends AStatement {
constructor.endMethod();
// Write a method to get static variable source
MethodWriter nameMethod = new MethodWriter(Opcodes.ACC_PUBLIC, GET_NAME_METHOD, visitor, globals.getStatements(), settings);
MethodWriter nameMethod = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, GET_NAME_METHOD);
nameMethod.visitCode();
nameMethod.getStatic(CLASS_TYPE, "$NAME", STRING_TYPE);
nameMethod.returnValue();
nameMethod.endMethod();
// Write a method to get static variable source
MethodWriter sourceMethod = new MethodWriter(Opcodes.ACC_PUBLIC, GET_SOURCE_METHOD, visitor, globals.getStatements(), settings);
MethodWriter sourceMethod = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, GET_SOURCE_METHOD);
sourceMethod.visitCode();
sourceMethod.getStatic(CLASS_TYPE, "$SOURCE", STRING_TYPE);
sourceMethod.returnValue();
sourceMethod.endMethod();
// Write a method to get static variable statements
MethodWriter statementsMethod =
new MethodWriter(Opcodes.ACC_PUBLIC, GET_STATEMENTS_METHOD, visitor, globals.getStatements(), settings);
MethodWriter statementsMethod = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, GET_STATEMENTS_METHOD);
statementsMethod.visitCode();
statementsMethod.getStatic(CLASS_TYPE, "$STATEMENTS", BITSET_TYPE);
statementsMethod.returnValue();
statementsMethod.endMethod();
// Write the method defined in the interface:
MethodWriter executeMethod = new MethodWriter(Opcodes.ACC_PUBLIC, scriptClassInfo.getExecuteMethod(), visitor,
globals.getStatements(), settings);
MethodWriter executeMethod = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, scriptClassInfo.getExecuteMethod());
executeMethod.visitCode();
write(executeMethod, globals);
write(classWriter, executeMethod, globals);
executeMethod.endMethod();
// Write all functions:
for (SFunction function : functions) {
function.write(visitor, settings, globals);
function.write(classWriter, globals);
}
// Write all synthetic functions. Note that this process may add more :)
@ -297,7 +283,7 @@ public final class SClass extends AStatement {
List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values());
globals.getSyntheticMethods().clear();
for (SFunction function : current) {
function.write(visitor, settings, globals);
function.write(classWriter, globals);
}
}
@ -307,7 +293,7 @@ public final class SClass extends AStatement {
// Fields
for (Constant constant : inits) {
visitor.visitField(
classVisitor.visitField(
Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
constant.name,
constant.type.getDescriptor(),
@ -317,7 +303,7 @@ public final class SClass extends AStatement {
// Initialize the constants in a static initializer
final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC,
WriterConstants.CLINIT, visitor, globals.getStatements(), settings);
WriterConstants.CLINIT, classVisitor, globals.getStatements(), settings);
clinit.visitCode();
for (Constant constant : inits) {
constant.initializer.accept(clinit);
@ -331,14 +317,14 @@ public final class SClass extends AStatement {
for (Map.Entry<String, Class<?>> classBinding : globals.getClassBindings().entrySet()) {
String name = classBinding.getKey();
String descriptor = Type.getType(classBinding.getValue()).getDescriptor();
visitor.visitField(Opcodes.ACC_PRIVATE, name, descriptor, null, null).visitEnd();
classVisitor.visitField(Opcodes.ACC_PRIVATE, name, descriptor, null, null).visitEnd();
}
// Write instance binding variables
for (Map.Entry<Object, String> instanceBinding : globals.getInstanceBindings().entrySet()) {
String name = instanceBinding.getValue();
String descriptor = Type.getType(instanceBinding.getKey().getClass()).getDescriptor();
visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, name, descriptor, null, null).visitEnd();
classVisitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, name, descriptor, null, null).visitEnd();
}
// Write any needsVarName methods for used variables
@ -346,7 +332,7 @@ public final class SClass extends AStatement {
String name = needsMethod.getName();
name = name.substring(5);
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
MethodWriter ifaceMethod = new MethodWriter(Opcodes.ACC_PUBLIC, needsMethod, visitor, globals.getStatements(), settings);
MethodWriter ifaceMethod = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, needsMethod);
ifaceMethod.visitCode();
ifaceMethod.push(extractedVariables.contains(name));
ifaceMethod.returnValue();
@ -355,8 +341,8 @@ public final class SClass extends AStatement {
// End writing the class and store the generated bytes.
visitor.visitEnd();
bytes = writer.toByteArray();
classVisitor.visitEnd();
bytes = classWriter.getClassBytes();
Map<String, Object> statics = new HashMap<>();
statics.put("$LOCALS", mainMethod.getMethods());
@ -369,14 +355,14 @@ public final class SClass extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(org.elasticsearch.painless.ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
// We wrap the whole method in a few try/catches to handle and/or convert other exceptions to ScriptException
Label startTry = new Label();
Label endTry = new Label();
Label startExplainCatch = new Label();
Label startOtherCatch = new Label();
Label endCatch = new Label();
writer.mark(startTry);
methodWriter.mark(startTry);
if (settings.getMaxLoopCounter() > 0) {
// if there is infinite loop protection, we do this once:
@ -384,8 +370,8 @@ public final class SClass extends AStatement {
Variable loop = mainMethod.getVariable(null, Locals.LOOP);
writer.push(settings.getMaxLoopCounter());
writer.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
methodWriter.push(settings.getMaxLoopCounter());
methodWriter.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
}
for (org.objectweb.asm.commons.Method method : getMethods) {
@ -393,77 +379,77 @@ public final class SClass extends AStatement {
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
Variable variable = mainMethod.getVariable(null, name);
writer.loadThis();
writer.invokeVirtual(Type.getType(scriptClassInfo.getBaseClass()), method);
writer.visitVarInsn(method.getReturnType().getOpcode(Opcodes.ISTORE), variable.getSlot());
methodWriter.loadThis();
methodWriter.invokeVirtual(Type.getType(scriptClassInfo.getBaseClass()), method);
methodWriter.visitVarInsn(method.getReturnType().getOpcode(Opcodes.ISTORE), variable.getSlot());
}
for (AStatement statement : statements) {
statement.write(writer, globals);
statement.write(classWriter, methodWriter, globals);
}
if (!methodEscape) {
switch (scriptClassInfo.getExecuteMethod().getReturnType().getSort()) {
case org.objectweb.asm.Type.VOID:
break;
case org.objectweb.asm.Type.BOOLEAN:
writer.push(false);
methodWriter.push(false);
break;
case org.objectweb.asm.Type.BYTE:
writer.push(0);
methodWriter.push(0);
break;
case org.objectweb.asm.Type.SHORT:
writer.push(0);
methodWriter.push(0);
break;
case org.objectweb.asm.Type.INT:
writer.push(0);
methodWriter.push(0);
break;
case org.objectweb.asm.Type.LONG:
writer.push(0L);
methodWriter.push(0L);
break;
case org.objectweb.asm.Type.FLOAT:
writer.push(0f);
methodWriter.push(0f);
break;
case org.objectweb.asm.Type.DOUBLE:
writer.push(0d);
methodWriter.push(0d);
break;
default:
writer.visitInsn(Opcodes.ACONST_NULL);
methodWriter.visitInsn(Opcodes.ACONST_NULL);
}
writer.returnValue();
methodWriter.returnValue();
}
writer.mark(endTry);
writer.goTo(endCatch);
methodWriter.mark(endTry);
methodWriter.goTo(endCatch);
// This looks like:
// } catch (PainlessExplainError e) {
// throw this.convertToScriptException(e, e.getHeaders($DEFINITION))
// }
writer.visitTryCatchBlock(startTry, endTry, startExplainCatch, PAINLESS_EXPLAIN_ERROR_TYPE.getInternalName());
writer.mark(startExplainCatch);
writer.loadThis();
writer.swap();
writer.dup();
writer.getStatic(CLASS_TYPE, "$DEFINITION", DEFINITION_TYPE);
writer.invokeVirtual(PAINLESS_EXPLAIN_ERROR_TYPE, PAINLESS_EXPLAIN_ERROR_GET_HEADERS_METHOD);
writer.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
writer.throwException();
methodWriter.visitTryCatchBlock(startTry, endTry, startExplainCatch, PAINLESS_EXPLAIN_ERROR_TYPE.getInternalName());
methodWriter.mark(startExplainCatch);
methodWriter.loadThis();
methodWriter.swap();
methodWriter.dup();
methodWriter.getStatic(CLASS_TYPE, "$DEFINITION", DEFINITION_TYPE);
methodWriter.invokeVirtual(PAINLESS_EXPLAIN_ERROR_TYPE, PAINLESS_EXPLAIN_ERROR_GET_HEADERS_METHOD);
methodWriter.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
methodWriter.throwException();
// This looks like:
// } catch (PainlessError | BootstrapMethodError | OutOfMemoryError | StackOverflowError | Exception e) {
// throw this.convertToScriptException(e, e.getHeaders())
// }
// We *think* it is ok to catch OutOfMemoryError and StackOverflowError because Painless is stateless
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, PAINLESS_ERROR_TYPE.getInternalName());
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, BOOTSTRAP_METHOD_ERROR_TYPE.getInternalName());
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, OUT_OF_MEMORY_ERROR_TYPE.getInternalName());
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, STACK_OVERFLOW_ERROR_TYPE.getInternalName());
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, EXCEPTION_TYPE.getInternalName());
writer.mark(startOtherCatch);
writer.loadThis();
writer.swap();
writer.invokeStatic(COLLECTIONS_TYPE, EMPTY_MAP_METHOD);
writer.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
writer.throwException();
writer.mark(endCatch);
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, PAINLESS_ERROR_TYPE.getInternalName());
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, BOOTSTRAP_METHOD_ERROR_TYPE.getInternalName());
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, OUT_OF_MEMORY_ERROR_TYPE.getInternalName());
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, STACK_OVERFLOW_ERROR_TYPE.getInternalName());
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, EXCEPTION_TYPE.getInternalName());
methodWriter.mark(startOtherCatch);
methodWriter.loadThis();
methodWriter.swap();
methodWriter.invokeStatic(COLLECTIONS_TYPE, EMPTY_MAP_METHOD);
methodWriter.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
methodWriter.throwException();
methodWriter.mark(endCatch);
}
public BitSet getStatements() {

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -62,8 +63,8 @@ public final class SContinue extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.goTo(continu);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.goTo(continu);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -68,9 +69,9 @@ public final class SDeclBlock extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
for (AStatement declaration : declarations) {
declaration.write(writer, globals);
declaration.write(classWriter, methodWriter, globals);
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -83,29 +84,29 @@ public final class SDeclaration extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
if (expression == null) {
Class<?> sort = variable.clazz;
if (sort == void.class || sort == boolean.class || sort == byte.class ||
sort == short.class || sort == char.class || sort == int.class) {
writer.push(0);
methodWriter.push(0);
} else if (sort == long.class) {
writer.push(0L);
methodWriter.push(0L);
} else if (sort == float.class) {
writer.push(0F);
methodWriter.push(0F);
} else if (sort == double.class) {
writer.push(0D);
methodWriter.push(0D);
} else {
writer.visitInsn(Opcodes.ACONST_NULL);
methodWriter.visitInsn(Opcodes.ACONST_NULL);
}
} else {
expression.write(writer, globals);
expression.write(classWriter, methodWriter, globals);
}
writer.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -107,32 +108,32 @@ public final class SDo extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
Label start = new Label();
Label begin = new Label();
Label end = new Label();
writer.mark(start);
methodWriter.mark(start);
block.continu = begin;
block.brake = end;
block.write(writer, globals);
block.write(classWriter, methodWriter, globals);
writer.mark(begin);
methodWriter.mark(begin);
if (!continuous) {
condition.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, end);
condition.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, end);
}
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), Math.max(1, block.statementCount), location);
methodWriter.writeLoopCounter(loopCounter.getSlot(), Math.max(1, block.statementCount), location);
}
writer.goTo(start);
writer.mark(end);
methodWriter.goTo(start);
methodWriter.mark(end);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -119,8 +120,8 @@ public class SEach extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
sub.write(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
sub.write(classWriter, methodWriter, globals);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -76,14 +77,14 @@ public final class SExpression extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
expression.write(writer, globals);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
expression.write(classWriter, methodWriter, globals);
if (methodEscape) {
writer.returnValue();
methodWriter.returnValue();
} else {
writer.writePop(MethodWriter.getType(expression.expected).getSize());
methodWriter.writePop(MethodWriter.getType(expression.expected).getSize());
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -173,27 +174,27 @@ public final class SFor extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
Label start = new Label();
Label begin = afterthought == null ? start : new Label();
Label end = new Label();
if (initializer instanceof SDeclBlock) {
initializer.write(writer, globals);
initializer.write(classWriter, methodWriter, globals);
} else if (initializer instanceof AExpression) {
AExpression initializer = (AExpression)this.initializer;
initializer.write(writer, globals);
writer.writePop(MethodWriter.getType(initializer.expected).getSize());
initializer.write(classWriter, methodWriter, globals);
methodWriter.writePop(MethodWriter.getType(initializer.expected).getSize());
}
writer.mark(start);
methodWriter.mark(start);
if (condition != null && !continuous) {
condition.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, end);
condition.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, end);
}
boolean allEscape = false;
@ -208,29 +209,29 @@ public final class SFor extends AStatement {
}
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
methodWriter.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
}
block.continu = begin;
block.brake = end;
block.write(writer, globals);
block.write(classWriter, methodWriter, globals);
} else {
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), 1, location);
methodWriter.writeLoopCounter(loopCounter.getSlot(), 1, location);
}
}
if (afterthought != null) {
writer.mark(begin);
afterthought.write(writer, globals);
writer.writePop(MethodWriter.getType(afterthought.expected).getSize());
methodWriter.mark(begin);
afterthought.write(classWriter, methodWriter, globals);
methodWriter.writePop(MethodWriter.getType(afterthought.expected).getSize());
}
if (afterthought != null || !allEscape) {
writer.goTo(start);
methodWriter.goTo(start);
}
writer.mark(end);
methodWriter.mark(end);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -28,7 +29,6 @@ import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import java.lang.invoke.MethodType;
@ -146,31 +146,31 @@ public final class SFunction extends AStatement {
}
/** Writes the function to given ClassVisitor. */
void write(ClassVisitor writer, CompilerSettings settings, Globals globals) {
void write(ClassWriter classWriter, Globals globals) {
int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;
if (synthetic) {
access |= Opcodes.ACC_SYNTHETIC;
}
final MethodWriter function = new MethodWriter(access, method, writer, globals.getStatements(), settings);
function.visitCode();
write(function, globals);
function.endMethod();
final MethodWriter methodWriter = classWriter.newMethodWriter(access, method);
methodWriter.visitCode();
write(classWriter, methodWriter, globals);
methodWriter.endMethod();
}
@Override
void write(MethodWriter function, Globals globals) {
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
if (settings.getMaxLoopCounter() > 0) {
// if there is infinite loop protection, we do this once:
// int #loop = settings.getMaxLoopCounter()
function.push(settings.getMaxLoopCounter());
function.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
methodWriter.push(settings.getMaxLoopCounter());
methodWriter.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
}
block.write(function, globals);
block.write(classWriter, methodWriter, globals);
if (!methodEscape) {
if (returnType == void.class) {
function.returnValue();
methodWriter.returnValue();
} else {
throw createError(new IllegalStateException("Illegal tree structure."));
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -89,19 +90,19 @@ public final class SIf extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
Label fals = new Label();
condition.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, fals);
condition.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
ifblock.continu = continu;
ifblock.brake = brake;
ifblock.write(writer, globals);
ifblock.write(classWriter, methodWriter, globals);
writer.mark(fals);
methodWriter.mark(fals);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -119,30 +120,30 @@ public final class SIfElse extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
Label fals = new Label();
Label end = new Label();
condition.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, fals);
condition.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
ifblock.continu = continu;
ifblock.brake = brake;
ifblock.write(writer, globals);
ifblock.write(classWriter, methodWriter, globals);
if (!ifblock.allEscape) {
writer.goTo(end);
methodWriter.goTo(end);
}
writer.mark(fals);
methodWriter.mark(fals);
elseblock.continu = continu;
elseblock.brake = brake;
elseblock.write(writer, globals);
elseblock.write(classWriter, methodWriter, globals);
writer.mark(end);
methodWriter.mark(end);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -78,14 +79,14 @@ public final class SReturn extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
if (expression != null) {
expression.write(writer, globals);
expression.write(classWriter, methodWriter, globals);
}
writer.returnValue();
methodWriter.returnValue();
}
@Override

View file

@ -20,6 +20,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -76,41 +77,41 @@ final class SSubEachArray extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
expression.write(writer, globals);
writer.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ISTORE), array.getSlot());
writer.push(-1);
writer.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ISTORE), index.getSlot());
expression.write(classWriter, methodWriter, globals);
methodWriter.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ISTORE), array.getSlot());
methodWriter.push(-1);
methodWriter.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ISTORE), index.getSlot());
Label begin = new Label();
Label end = new Label();
writer.mark(begin);
methodWriter.mark(begin);
writer.visitIincInsn(index.getSlot(), 1);
writer.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
writer.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
writer.arrayLength();
writer.ifICmp(MethodWriter.GE, end);
methodWriter.visitIincInsn(index.getSlot(), 1);
methodWriter.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
methodWriter.arrayLength();
methodWriter.ifICmp(MethodWriter.GE, end);
writer.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
writer.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
writer.arrayLoad(MethodWriter.getType(indexed));
writer.writeCast(cast);
writer.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
methodWriter.arrayLoad(MethodWriter.getType(indexed));
methodWriter.writeCast(cast);
methodWriter.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
methodWriter.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
}
block.continu = begin;
block.brake = end;
block.write(writer, globals);
block.write(classWriter, methodWriter, globals);
writer.goTo(begin);
writer.mark(end);
methodWriter.goTo(begin);
methodWriter.mark(end);
}
@Override

View file

@ -20,6 +20,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Globals;
@ -95,45 +96,45 @@ final class SSubEachIterable extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
expression.write(writer, globals);
expression.write(classWriter, methodWriter, globals);
if (method == null) {
org.objectweb.asm.Type methodType = org.objectweb.asm.Type
.getMethodType(org.objectweb.asm.Type.getType(Iterator.class), org.objectweb.asm.Type.getType(Object.class));
writer.invokeDefCall("iterator", methodType, DefBootstrap.ITERATOR);
methodWriter.invokeDefCall("iterator", methodType, DefBootstrap.ITERATOR);
} else {
writer.invokeMethodCall(method);
methodWriter.invokeMethodCall(method);
}
writer.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ISTORE), iterator.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ISTORE), iterator.getSlot());
Label begin = new Label();
Label end = new Label();
writer.mark(begin);
methodWriter.mark(begin);
writer.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
writer.invokeInterface(ITERATOR_TYPE, ITERATOR_HASNEXT);
writer.ifZCmp(MethodWriter.EQ, end);
methodWriter.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
methodWriter.invokeInterface(ITERATOR_TYPE, ITERATOR_HASNEXT);
methodWriter.ifZCmp(MethodWriter.EQ, end);
writer.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
writer.invokeInterface(ITERATOR_TYPE, ITERATOR_NEXT);
writer.writeCast(cast);
writer.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
methodWriter.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
methodWriter.invokeInterface(ITERATOR_TYPE, ITERATOR_NEXT);
methodWriter.writeCast(cast);
methodWriter.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
methodWriter.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
}
block.continu = begin;
block.brake = end;
block.write(writer, globals);
block.write(classWriter, methodWriter, globals);
writer.goTo(begin);
writer.mark(end);
methodWriter.goTo(begin);
methodWriter.mark(end);
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -64,10 +65,10 @@ public final class SThrow extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
expression.write(writer, globals);
writer.throwException();
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
expression.write(classWriter, methodWriter, globals);
methodWriter.throwException();
}
@Override

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -108,34 +109,34 @@ public final class STry extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
Label begin = new Label();
Label end = new Label();
Label exception = new Label();
writer.mark(begin);
methodWriter.mark(begin);
block.continu = continu;
block.brake = brake;
block.write(writer, globals);
block.write(classWriter, methodWriter, globals);
if (!block.allEscape) {
writer.goTo(exception);
methodWriter.goTo(exception);
}
writer.mark(end);
methodWriter.mark(end);
for (SCatch catc : catches) {
catc.begin = begin;
catc.end = end;
catc.exception = catches.size() > 1 ? exception : null;
catc.write(writer, globals);
catc.write(classWriter, methodWriter, globals);
}
if (!block.allEscape || catches.size() > 1) {
writer.mark(exception);
methodWriter.mark(exception);
}
}

View file

@ -19,6 +19,7 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@ -110,38 +111,38 @@ public final class SWhile extends AStatement {
}
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
methodWriter.writeStatementOffset(location);
Label begin = new Label();
Label end = new Label();
writer.mark(begin);
methodWriter.mark(begin);
if (!continuous) {
condition.write(writer, globals);
writer.ifZCmp(Opcodes.IFEQ, end);
condition.write(classWriter, methodWriter, globals);
methodWriter.ifZCmp(Opcodes.IFEQ, end);
}
if (block != null) {
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), Math.max(1, block.statementCount), location);
methodWriter.writeLoopCounter(loopCounter.getSlot(), Math.max(1, block.statementCount), location);
}
block.continu = begin;
block.brake = end;
block.write(writer, globals);
block.write(classWriter, methodWriter, globals);
} else {
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), 1, location);
methodWriter.writeLoopCounter(loopCounter.getSlot(), 1, location);
}
}
if (block == null || !block.allEscape) {
writer.goTo(begin);
methodWriter.goTo(begin);
}
writer.mark(end);
methodWriter.mark(end);
}
@Override

View file

@ -20,7 +20,7 @@ import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
*/
esplugin {
description 'The ICU Analysis plugin integrates Lucene ICU module into elasticsearch, adding ICU relates analysis components.'
description 'The ICU Analysis plugin integrates the Lucene ICU module into Elasticsearch, adding ICU-related analysis components.'
classname 'org.elasticsearch.plugin.analysis.icu.AnalysisICUPlugin'
}

View file

@ -109,4 +109,25 @@ public class AzureStorageCleanupThirdPartyTests extends AbstractThirdPartyReposi
}));
future.actionGet();
}
// override here to mute only for Azure, please remove this overload when un-muting
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/47202")
@Override
public void testCreateSnapshot() {
super.testCreateSnapshot();
}
// override here to mute only for Azure, please remove this overload when un-muting
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/47202")
@Override
public void testCleanup() throws Exception {
super.testCleanup();
}
// override here to mute only for Azure, please remove this overload when un-muting
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/47202")
@Override
public void testListChildren() throws Exception {
super.testListChildren();
}
}

View file

@ -21,7 +21,7 @@
"parts":{
"index":{
"type":"list",
"description":"A comma-separated list of index names to limit the returned information"
"description":"Comma-separated list or wildcard expression of index names to limit the returned information"
}
}
}
@ -32,6 +32,11 @@
"type":"string",
"description":"a short version of the Accept header, e.g. json, yaml"
},
"active_only":{
"type":"boolean",
"description":"If `true`, the response only includes ongoing shard recoveries",
"default":false
},
"bytes":{
"type":"enum",
"description":"The unit in which to display byte values",
@ -49,6 +54,11 @@
"pb"
]
},
"detailed":{
"type":"boolean",
"description":"If `true`, the response includes detailed information about shard recoveries",
"default":false
},
"master_timeout":{
"type":"time",
"description":"Explicit operation timeout for connection to master node"
@ -62,6 +72,10 @@
"description":"Return help information",
"default":false
},
"index":{
"type":"list",
"description":"Comma-separated list or wildcard expression of index names to limit the returned information"
},
"s":{
"type":"list",
"description":"Comma-separated list of column names or column aliases to sort by"

Some files were not shown because too many files have changed in this diff Show more