mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-04-25 07:37:19 -04:00
Merge remote-tracking branch 'es/master' into enrich
This commit is contained in:
commit
197c1d59d4
197 changed files with 2065 additions and 1787 deletions
|
@ -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:
|
||||
|
||||
|
|
|
@ -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[]
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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*
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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[]
|
||||
|
|
|
@ -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
|
||||
----
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>>.
|
||||
|
|
|
@ -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>>.
|
||||
|
||||
--
|
||||
|
||||
|
|
|
@ -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[]
|
||||
|
|
124
docs/reference/monitoring/production.asciidoc
Normal file
124
docs/reference/monitoring/production.asciidoc
Normal 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].
|
29
docs/reference/monitoring/troubleshooting.asciidoc
Normal file
29
docs/reference/monitoring/troubleshooting.asciidoc
Normal 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 … we’re 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>>.
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]]
|
||||
|
|
|
@ -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`::
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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="^,^"]
|
||||
|===
|
||||
|
|
|
@ -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[]
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
// to be both loaded from and stored to
|
||||
lhs.load(writer, globals); // load the current 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(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
|
||||
// to the promotion type between the lhs and rhs types
|
||||
rhs.write(writer, globals); // write the bytecode for the rhs
|
||||
methodWriter.writeCast(there); // if necessary cast the current lhs's value
|
||||
// to the promotion type between the lhs and rhs types
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
||||
|
|
|
@ -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."));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue